New in UIKit in iOS 8

With all the excitement surrounding a new programing language and another major version bump in Xcode, I've found myself pleasantly surprised with some of the new API in UIKit in iOS 8. I wanted to mention a few new additions that may have managed to fly under the radar.

UIAlertController

Goodbye UIAlertView and UIActionSheet. Hello UIActionController and block-based callbacks. Provide UIActionController with a styleType (might we see new styles in the future?), and the syntax is now identical between an actionsheet and an alertview. Big fan of the UIAlertView+Blocks and UIActionSheet+Blocks categories out there? Yes, they are great and I frequently pull them in, but I prefer to use Apple API when I can. Every added dependency is one more thing to maintain (yes, even CocoaPods) or inspect for warnings/bugs when a new version of iOS is introduced.

// Actionsheet-styled alert controller
let alertController: UIAlertController = UIAlertController(title: "Action Sheet", message: "Woot woot!", preferredStyle: .ActionSheet)

// Add cancel action
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
    // Cancel
}
alertController.addAction(cancelAction)

// Add confirm action
let confirmAction: UIAlertAction = UIAlertAction(title: "Confirm", style: .Default) { action -> Void in
    // Confirm
}
alertController.addAction(confirmAction)

// Present alert controller
self.presentViewController(alertController, animated: true, completion: nil)

UIVisualEffectsView

Been using iOS 7 hacks to add blur effects to your app? UIVisualEffectsView will be a welcome sight. You can now created blur views and add them to your backgrounds, imageviews, or wherever else you please.

UIVisualEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
visualEffectView.frame = someView.frame;
[self.view addSubview:visualEffectView];

Layout Margins

Confused by these -8s you see in your IB AutoLayout constraints? Me too. In iOS 8 Apple introduces layout margins on UIViews. Layout margins let you define the default whitespace surrounding your view (think of it as padding). These layout margins also cascade down to subviews that are pinned to the edge of their parent view.

From the UIView header file:

/*
 -layoutMargins returns a set of insets from the edge of the view's bounds that denote a default spacing for laying out content.
 If preservesSuperviewLayoutMargins is YES, margins cascade down the view tree, adjusting for geometry offsets, so that setting the left value of layoutMargins on a superview will affect the left value of layoutMargins for subviews positioned close to the left edge of their superview's bounds
 If your view subclass uses layoutMargins in its layout or drawing, override -layoutMarginsDidChange in order to refresh your view if the margins change.
*/

It appears by default Xcode 6 gives a view layout margins of {8,8,8,8}. With layout margins only supported in iOS 8+ this may or may not cause immediate issues if you build you project in Xcode 6 for iOS 7. A solution until you can support iOS 8+ is to select the constraint in IB and unselect "Relative to margin", then readjust the constant from -8 back to 0, if needed.

What Else?

  • UITraitCollection class can now be used to describe an object like UIView or UIViewController in terms of size, scale, and idiom traits
  • UISplitViewController now supported on iPhone and iPad -- oh hai, iPhone 6 Plus
  • New properties on UINavigationController including hidesBarsOnTap, hidesBarsOnSwipe, navigationBarHidden, and others

  • Take users directly to your app's settings in the iOS Settings app by passing UIApplicationOpenSettingsURLString to openUrl:

Learn More