Home > Articles > Mobile Application Development & Programming

  • Print
  • + Share This
Like this article? We recommend

Adaptive Rendering on the iPhone and iPad

Earlier in this article, I mentioned the adaptive rendering capability of the new UIAlertController class. Let's see how it works.

Consider the following code snippet:

var alertController = UIAlertController(
  title: "Confirm Deletion",
  message: "Are you sure you want to delete this item?",
  preferredStyle: UIAlertControllerStyle.ActionSheet)

var yesAction = UIAlertAction(
  title: "Yes", style: UIAlertActionStyle.Destructive) {
      (action) -> Void in
       println("Yes")
}

var yesAndBackupAction = UIAlertAction(
  title: "Yes and Backup", style: UIAlertActionStyle.Default) {
      (action) -> Void in
       println("Yes and Backup")
}

var noAction = UIAlertAction(
  title: "No", style: UIAlertActionStyle.Cancel) {
      (action) -> Void in
       println("No")
}

alertController.addAction(yesAction)
alertController.addAction(yesAndBackupAction)
alertController.addAction(noAction)


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

When run on the iPhone, this code displays an action sheet, as shown in Figure 8.

Figure 8

Figure 8 Displaying the action sheet on an iPhone.

However, when you run this code on an iPad, it will crash, with the following message:


Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application
has presented a UIAlertController () of style
UIAlertControllerStyleActionSheet. 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.'

Basically, the message says that when you run this piece of code on an iPad, it will display the action sheet as a popover, and you need to specify explicitly where to display the popover. To fix this problem, add the highlighted code to the example:

@IBAction func btnAlert(sender: AnyObject) {
 var alertController = UIAlertController(
   title: "Confirm Deletion",
   message: "Are you sure you want to delete this item?",
   preferredStyle: UIAlertControllerStyle.ActionSheet)


   var yesAction = UIAlertAction(
     title: "Yes", style: UIAlertActionStyle.Destructive){
         (action) -> Void in
          println("Yes")
   }


   var yesAndBackupAction = UIAlertAction(
     title: "Yes and Backup", style: UIAlertActionStyle.Default) {
         (action) -> Void in
          println("Yes and Backup")
   }


    var noAction = UIAlertAction(
      title: "No", style: UIAlertActionStyle.Cancel) {
          (action) -> Void in
           println("No")
    }


    alertController.addAction(yesAction)
    alertController.addAction(yesAndBackupAction)
    alertController.addAction(noAction)


    var popOver = alertController.popoverPresentationController
    popOver?.sourceView  = sender as UIView
    popOver?.sourceRect = (sender as UIView).bounds
    popOver?.permittedArrowDirections = UIPopoverArrowDirection.Any


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

This code obtains the instance of the UIPopoverPresentationController from the UIAlertController instance and sets its sourceView and sourceRect properties to the location of the sender (sender is an argument passed in through an IBAction; in this example it's a UIButton). You also indicate that the arrow for the popover can be in any direction; the direction of the arrow shown during runtime thus depends on the location of the button. If you run the code snippet on the iPad, the popover appears as shown in Figure 9.

Figure 9

Figure 9 Displaying the action sheet as a popover on the iPad.

The beauty of the UIAlertController is that the code snippet shown here runs without modification on the iPhone and the iPad. When run on the iPhone, it displays an action sheet; when run on the iPad, it displays a popover.

  • + Share This
  • 🔖 Save To Your Account