2014-09-25 32 views
43

Attualmente sto avendo grossi problemi con il mio foglio di lavoro. Su iPhone funziona benissimo, ma su iPad si blocca soloSwift UIAlertController -> ActionSheet iPad iOS8 si blocca

ho creare un nuovo progetto con un solo tasto

import UIKit 

extension ViewController : UIActionSheetDelegate { 

    func actionSheet(actionSheet: UIActionSheet, didDismissWithButtonIndex buttonIndex: Int) { 

     if actionSheet.tag == 0 { 
      if buttonIndex == 1 { 
       // doing something for "product page" 
      } else if (buttonIndex == 2) { 
       // doing something for "video" 
      } 
     } 
    } 

} 

class ViewController: UIViewController, UIActionSheetDelegate { 
    @IBAction func test(sender: AnyObject) { 

     let systemVersion: NSInteger = (UIDevice.currentDevice().systemVersion as NSString).integerValue 
     if systemVersion < 8 { 
      // iOS7: 
      let action:UIActionSheet = UIActionSheet(title: "Change Map Type", delegate: self, cancelButtonTitle: "Back", destructiveButtonTitle: nil, otherButtonTitles: "Product Page", "Video") 
      action.tag = 0 
      action.showInView(self.view) 
     } else { 
      // iOS8: 
      let alertController: UIAlertController = UIAlertController(title: "Change Map Type", message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet) 
      let cancelAction: UIAlertAction = UIAlertAction(title: "Back", style: UIAlertActionStyle.Cancel, handler: nil) 
      let button1action: UIAlertAction = UIAlertAction(title: "Product Page", style: UIAlertActionStyle.Default, handler: { (action: UIAlertAction!) ->() in 
       // doing something for "product page" 
      }) 
      let button2action: UIAlertAction = UIAlertAction(title: "Video", style: UIAlertActionStyle.Default, handler: { (action: UIAlertAction!) ->() in 
       // doing something for "video" 
      }) 
      alertController.addAction(cancelAction) 
      alertController.addAction(button1action) 
      alertController.addAction(button2action) 

      self.presentViewController(alertController, animated: true, completion: nil) 
     } 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
    } 

} 

Come ho detto su iPhone funziona, ma se clicco il tasto su iPad il App blocca con

2014-09-25 14: 54: 52,784 Test [9541: 1.970.048] * terminazione app a causa di eccezione non identificata 'NSGenericException', la ragione: 'L'applicazione ha presentato una UIAlertController() di stile UIAlertControllerStyleActionSheet. Il modalPresentationStyle di un UIAlertController con questo stile è UIModalPresentationPopover. È necessario che fornisca le informazioni sulla posizione per questo popover tramite l'avviso popoverPresentationController del controller. È necessario fornire un sourceView e un oggetto SourceBar o un oggetto BarButtonItem. Se questa informazione è non nota quando si presenta il controller degli avvisi, è possibile fornirlo in il metodo UIPopoverPresentationControllerDelegate -prepareForPopoverPresentation. ' * Primo bando laterale stack: (0 CoreFoundation 0x00613df6 exceptionPreprocess + 182 1 libobjc.A.dylib
0x01fdaa97 objc_exception_throw + 44 2 UIKit
0x0164da37 - [UIPopoverPresentationController presentationTransitionWillBegin] + 3086 3 UIKit
0x00f54f75 __71- [UIPresentationController _initViewHierarchyForPresentationSuperview:] _ block_invoke + 1.666 4 UIKit 0x00f53554 __56- [UIPresentationController runTransitionForCurrentState] _block_invoke + 226 5 UIKit
0x00f8721b __40 + [UIViewController _scheduleTransition:] _ block_invoke + 18 6 UIKit 0x00e4d62e ___afterCACommitHandler_block_invoke + 15 7 UIKit 0x00e4d5d9 _applyBlockToCFArrayCopiedToStack + 415 8 UIKit
0x00e4d3ee _afterCACommitHandler + 545 9 CoreFoundation
0x00536fbe __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION
+ 30 10 CoreFoundation 0x00536f00 __CFRunLoopDoObservers + 400 11 CoreFoundation 0x0052c93a __CFRunLoopRun + 1226 12 CoreFoundation 0x0052c1ab CFRunLoopRunSpecific + 443 13 CoreFoundation
0x0052bfdb CFRunLoopRunInMode + 123 14 GraphicsServices
0x0438424f GSEventRunModal + 192 15 GraphicsServices
0x0438408c GSEventRun + 104 16 UIKit
0x00e23e16 UIApplicationMain + 1526 17 Test
0x00085e9e top_level_code + 78 18 Test
0x00085edb principale + 43 19 libdyld.dylib
0x0273eac9 avviare + 1 20 ???
0x00000001 0x0 + 1) libC++ abi.dylib: termina con eccezione non identificata di tipo NSException

progetto può essere trovato alla https://www.dropbox.com/s/54jqd8nsc67ll5g/test.zip?dl=0 per il download e provare.

+0

quel post è molto simile alla mia risposta ... tranne l'eccezione. http://stackoverflow.com/questions/26037657/swift-uiactionsheet-crashes-on-ipad – holex

+0

Sì, ma si blocca ancora –

+0

aggiornerò presto la mia risposta ... – holex

risposta

126

Il messaggio di errore indica che è necessario fornire al controller di avviso popoverPresentationController un percorso in modo che possa posizionarsi correttamente. Questo è facile da fare: basta controllare se c'è un controller popover e aggiungere il mittente come sorgente.

Se il pulsante è un UIBarButtonItem:

if let popoverController = alertController.popoverPresentationController { 
    popoverController.barButtonItem = sender 
} 
self.presentViewController(alertController, animated: true, completion: nil) 

Altrimenti:

if let popoverController = alertController.popoverPresentationController { 
    popoverController.sourceView = sender 
    popoverController.sourceRect = sender.bounds 
} 
self.presentViewController(alertController, animated: true, completion: nil) 
+5

con swift 1.2, è ora richiesto di fare: popoverController.sourceView = sender as! UIView – Xerion

+0

'popoverController.sourceRect = sender.bounds' fa apparire ActionSheet nell'angolo in alto a sinistra dell'iPad. Invece puoi usare 'popoverController.sourceRect = sender.frame' –

+0

' sender.bounds' funziona per me - sourceRect è 'Il rettangolo nella vista specificata in cui ancorare il popover'. Prendo questo per dire che è nello spazio delle coordinate del sourceView e quindi .bounds – leafcutter

6

provare questo

alertController.popoverPresentationController?.sourceView = self.view 
+0

grazie, mi ha salvato dagli arresti anomali, ma mostra nell'angolo in alto a sinistra ... – djdance

1

Nate Cook è totalmente ragione però io farei così ho rilevare se è iPad o iPhone.

questo è per barButtonItem:

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad){ 

      if let currentPopoverpresentioncontroller = alertController.popoverPresentationController{ 
       currentPopoverpresentioncontroller.barButtonItem = sender as! UIBarButtonItem 
       currentPopoverpresentioncontroller.permittedArrowDirections = UIPopoverArrowDirection.down; 
       self.present(alertController, animated: true, completion: nil) 
      } 
     }else{ 
      self.present(alertController, animated: true, completion: nil) 
     } 
0

var = actionSheet UIAlertController (titolo: "Seleziona fotocamera o Fototeca", un messaggio: "", preferredStyle: .actionSheet)

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad){ 
     actionSheet = UIAlertController(title: "Please Select Camera or Photo Library", message: "", preferredStyle: .alert) 
    } 

    actionSheet.addAction(UIAlertAction(title: "Upload a Photo", style: .default, handler: { (UIAlertAction) in 
     self.openPhotoLibrary() 
    })) 
    actionSheet.addAction(UIAlertAction(title: "Take a Photo", style: .default, handler: { (UIAlertAction) in 
     self.openCamera() 
    })) 
    actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) 
    self.present(actionSheet, animated: true, completion: nil) 
Problemi correlati