Search code examples
iosautolayoutios-app-extensionios8-today-widgetuiedgeinsets

Properly align elements in Notification Center widget using Auto Layout


I'm having difficulties obtaining the proper alignment of elements in my Notification Center extension. I would like to align the elements to respect the default margins applied - it should be left aligned with the first character in the app name, and right aligned with some padding applied. If you notice the lines in the Calendar extension, I am trying to match those margins exactly (although those too don't seem to be quite right in some cases).

I have my elements set up using Auto Layout, all done programatically. I've set the leading equal to self.view's leading and trailing to self.view's trailing. When I run the extension on various devices the lading padding is inconsistent while the trailing is always clear to the far edge.

If I change it from just Leading and Trailing to LeadingMargin and TrailingMargin it appears the exact same. If I change it to align the element's Leading with the view's LeadingMargin and trailing with view's TrailingMargin then the trailing seems to be the desired margin but the leading is pushed too far to the right on iPhone 6 even though it's perfect on the iPad. On the iPhone 6 Plus in landscape the leading is aligned with the beginning of the app icon and the trailing has no padding, but only sometimes! Other times it does add the margins.

How do you configure this to properly align the elements?

I have not implemented widgetMarginInsetsForProposedMarginInsets.

//viewDidLoad:
let label = UILabel()
label.backgroundColor = UIColor.blueColor()
label.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(label)
self.view.addConstraint(NSLayoutConstraint(item: label, attribute: .Top, relatedBy: .Equal, toItem: self.view, attribute: .Top, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: label, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: label, attribute: .Leading, relatedBy: .Equal, toItem: self.view, attribute: .Leading, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: label, attribute: .Trailing, relatedBy: .Equal, toItem: self.view, attribute: .Trailing, multiplier: 1, constant: 0))
let heightConstraint = NSLayoutConstraint(item: label, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .Height, multiplier: 1, constant: 100)
heightConstraint.priority = 999
self.view.addConstraint(heightConstraint)

iPhone 6 Portrait: enter image description here

iPhone 6 Plus Portrait: enter image description here

iPhone 6 Plus Landscape: enter image description here

iPad (Portrait/Landscape): enter image description here


Solution

  • Looks like this is an issue affecting iOS 8.2 and prior, as it's behaving as expected and is consistent if I use Leading -> Leading and Trailing -> TrailingMargin in iOS 8.3.