Swift UIActionSheet crashes on iPad?
Asked Answered
P

2

2

I m currently running into complete frustrations as i can't find any error, but my ActionSheet crashes on iPad but works well on iPhone here is the code of the action

if (view.annotation.title as String!) == "San Francisco" {

                currentLat = 37.615223
                    currentLong = -122.389977

                url = "www.google.de"

                let action:UIActionSheet = UIActionSheet(title: "Change Map Type", delegate: self, cancelButtonTitle: "Back", destructiveButtonTitle: nil, otherButtonTitles: "Product Page", "Video")
                action.showInView(self.view)
                action.tag = 0
                VideoID = "XXXXXX"


            }

So the action that should be handled is

if actionSheet.tag == 0{
            if buttonIndex == 1{ performSegueWithIdentifier("showShop", sender: self) }
            if buttonIndex == 2{ UIApplication.sharedApplication().openURL(NSURL(string: "http://www.youtube.com/watch?v=\(youtubeVideoID)")) }
            //if buttonIndex == 2{ performSegueWithIdentifier("showYoutube", sender: self) }

        }

The Youtube one works fine, on iPhone and iPad, the "showShop" does work fine on iPhone but not on iPad

The "showShop" Segue forward to my ViewControllerShopView that looks like

import UIKit

class ViewControllerShopView: UIViewController {
/* ################################################## IBOutlets ################################################## */
    @IBOutlet weak var activity3: UIActivityIndicatorView!
    @IBOutlet weak var webView: UIWebView!
/* ################################################## viewDidLoad ################################################## */
    override func viewDidLoad() {
        super.viewDidLoad()

        loadurl()
    }
/* ################################################## didReceiveMemoryWarning ################################################## */
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()

        println("memory warning")
    }
/* ################################################## viewWillAppear ################################################## */
    override func viewWillAppear(animated: Bool) {

        loadurl()
    }
/* ################################################## loadurl func ################################################## */
    func loadurl(){
        var loadingurl = "google.com"
        var homeurl = "google1.com"
        loadingurl = url
        let webviewURL = NSURL(string: loadingurl)
        let request = NSURLRequest(URL: webviewURL)
        webView.loadRequest(request)
    }
/* ################################################## HomeButton ################################################## */
    @IBAction func Reload(sender: AnyObject) {

        var loadingurl = "google.com"
        var homeurl = "google1.com"
        loadingurl = url
        let webviewURL = NSURL(string: loadingurl)
        let request = NSURLRequest(URL: webviewURL)
        webView.loadRequest(request)
    }
/* ################################################## Activity Indicator ################################################## */
    func webViewDidStartLoad(_ : UIWebView){activity3.startAnimating()}
    func webViewDidFinishLoad(_ : UIWebView){activity3.stopAnimating()}



}

but the Segue never been done on iPad, it simply crashes on the Segue.

Anyone a idea what could be wrong?

Pamplona answered 25/9, 2014 at 11:37 Comment(10)
on iOS8+ you need to use the UIActionController instead, the UIActionSheet and UIAlertView are deprecated, more info about it here: developer.apple.com/library/IOs/documentation/UIKit/Reference/…, however you have not mentioned which iOS versions are affected...Fomentation
@Fomentation how my action sheet must look as actioncontroller?Pamplona
they look the same, because the UIAlertController is a 'merged' (or 'combined' if you'd like) version of UIActionSheet and UIAlertView in one class, so the end-user won't spot the difference, but under the hood (in your code) you need to handle such deprecation if your project supports both iOS7 and iO8.Fomentation
@Fomentation i mean look like in code :) sorry. Currently it only supports ios8Pamplona
no, the UIAlertController works totally different than the old UIActionSheet or UIAlertView did. (SORRY! I mistyped the name of the class above!)Fomentation
now i m complet confused :) so "there is no" easy work around for this to get it to ios8 on ipad?Pamplona
no, in iOS7 you can use only UIAlertView or UIActionSheet but in iOS8 you have to use the UIActionController only. the implementation is different, you need to check which iOS version runs on the device in runtime to work with the proper classes.Fomentation
@Fomentation see post belowPamplona
no, see my post below. that is the proper way if you support both iOS7 and iOS8.Fomentation
Let us continue this discussion in chat.Pamplona
F
7

you need to check the system version in runtime if your project supports both iOS7 and iOS8; you can insert this snippet into any of your methods:

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)

    // for iPAD support:
    alertController.popoverPresentationController?.sourceView = self.view
    alertController.popoverPresentationController?.sourceRect = CGRectMake(self.view.bounds.width / 2.0, self.view.bounds.height / 2.0, 1.0, 1.0) // this is the center of the screen currently but it can be any point in the view

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

and your class needs to conform the UIActionSheetDelegate for the UIActionSheet class:

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"
            }
        }
    }

}
Fomentation answered 25/9, 2014 at 12:30 Comment(4)
Getting a crash with *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application has presented a UIAlertController (<UIAlertController: 0x815c8c10>) of style UIAlertControllerStyleActionSheet.Pamplona
The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. You must provide location information for this popover through the alert controller's popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem. If this information is not known when you present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.'Pamplona
I just testet it on a new project with simulator with Xcode6 6A313 - works for iphone but crashes on ipadPamplona
Here is the clean sample project dropbox.com/s/54jqd8nsc67ll5g/test.zip?dl=0 works on iPhone but crashes on iPadPamplona
P
-1

also tried this

@IBAction func BTfindme(sender: AnyObject) {
        let actionSheetController: UIAlertController = UIAlertController(title: "Action Sheet", message: "Test", preferredStyle: .ActionSheet)
        let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
            }
        actionSheetController.addAction(cancelAction)

        let ActionOne: UIAlertAction = UIAlertAction(title: "Action one", style: .Default) { action -> Void in
            }
        actionSheetController.addAction(ActionOne)

        let ActionTwo: UIAlertAction = UIAlertAction(title: "Action two", style: .Default) { action -> Void in
            }
        ActionTwo.addAction(choosePictureAction)
        self.presentViewController(actionSheetController, animated: true, completion: nil)
    }

and this also force a crash on ipad but not on iphone

Pamplona answered 25/9, 2014 at 12:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.