Tuesday, June 13, 2017

Objective-C/Swift 3 avoid crashes in iPad in an iPhone Application

Targeting iOS app only for iPhone devices and run it on iPad devices, App gets crashed for UIAlertController(actionSheet) and UIAlertController.

Ever faced?

Let’s see the reason for crash and the fix for it.

(I am going to use Swift 3.0 in this post)


UIAlertController(actionSheet)




        let optionsMenu = UIAlertController(title: nil, message: "", 
                                                                     preferredStyle: .actionSheet)

        let deleteAction = UIAlertAction(title: “Delete”), style: .destructive, 
                                                                                                  handler: {
            (alert: UIAlertAction!) -> Void in
            //Delete Action
        })

        let saveAction = UIAlertAction(title: “Edit”, style: .default, handler: {
            (alert: UIAlertAction!) -> Void in
             // Edit Action
        })

        let cancelAction = UIAlertAction(title: “Cancel”, style: .cancel, handler: {
            (alert: UIAlertAction!) -> Void in
             //Cancel Action
        })

        optionsMenu.addAction(saveAction)
        optionsMenu.addAction(deleteAction)
        optionsMenu.addAction(cancelAction)

       self.present(optionMenu, animated: true, completion: nil)



 The above code works fine on iPhone device, But crashes on iPad device.

 The reason is in iPad, The presentation is going to be like a popover. 

 So we need to give either sourceView or barButtonItem as a source to the 
 popover as shown below.




   if (UIDevice.current.userInterfaceIdiom == .pad) {

       if let presentation = optionMenu.popoverPresentationController {

          presentation.barButtonItem = ((self.navigationItem.rightBarButtonItems)!)[0]

       }

  }




UIActivityViewController


  let sharingItems = [“share me….”] as [Any]

  let activityViewController = UIActivityViewController(activityItems: sharingItems, 
                                                                                     applicationActivities: nil)

   activityViewController.completionWithItemsHandler = 
                                                               {activity, completed, items, error in    
        }             
  
   self.present(activityViewController, animated: true, completion: nil)

    Same thing happens with UIActivityViewController. It crashes in iPad.
    Here also we need to provide sourceView/barButtonItem for iPad.

    if let popOverVC = activityViewController.popoverPresentationController { 

         if let navItems = self.navigationItem.rightBarButtonItems {
                popOverVC.barButtonItem = navItems[0]
         }

         else {
             popOverVC.sourceView = self.view
        }


    }



Hope this post is useful. Feel free to comment incase of any queries.