I am trying to switch the Autolayout constraints of my project for each orientation and am doing so by programmatically removing and adding a portrait and landscape set of NSAutoLayoutConstraints. I have the correct auto layout constraints (I think) for the layout for both orientations. My storyboard is not using Size Classes for compatibility.
I have taken screenshots of the correct layouts. The red portion is a UIView colored red.
My viewWillLayoutSubviews: is
- (void)viewWillLayoutSubviews {
[self.termToolbar invalidateIntrinsicContentSize];
}
and all the constraints adding and removing is in updateViewConstraints
When starting the app in portrait orientation and then rotating to landscape, I get a constraint error:
2015-07-26 10:50:42.856 reproduce[1084:23311] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<_UILayoutSupportConstraint:0x786436c0 V:[_UILayoutGuide:0x7864cb70(20)]>",
"<_UILayoutSupportConstraint:0x78643680 V:|-(0)-[_UILayoutGuide:0x7864cb70] (Names: '|':UIView:0x7864ca90 )>",
"<NSLayoutConstraint:0x78657bc0 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7864ca90(480)]>",
"<NSLayoutConstraint:0x78657bf0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7864ca90(320)]>",
"<NSLayoutConstraint:0x786593c0 V:[_UILayoutGuide:0x7864cb70]-(0)-[UISearchBar:0x78a21a70]>",
"<NSLayoutConstraint:0x786593f0 V:[UISearchBar:0x78a21a70]-(0)-[UITableView:0x7982aa00]>",
"<NSLayoutConstraint:0x78659420 V:[UITableView:0x7982aa00]-(0)-[UIView:0x78a216f0]>",
"<NSLayoutConstraint:0x78620570 V:[UIView:0x78a216f0]-(0)-[UIToolbar:0x78b81d00]>",
"<NSLayoutConstraint:0x786205a0 V:[UIToolbar:0x78b81d00]-(0)-| (Names: '|':UIView:0x7864ca90 )>",
"<NSLayoutConstraint:0x786590a0 UIView:0x78a216f0.height == 0.75*UIView:0x78a216f0.width>",
"<NSLayoutConstraint:0x786596d0 H:|-(0)-[UIView:0x78a216f0] (Names: '|':UIView:0x7864ca90 )>",
"<NSLayoutConstraint:0x78659720 H:[UIView:0x78a216f0]-(0)-| (Names: '|':UIView:0x7864ca90 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x786593f0 V:[UISearchBar:0x78a21a70]-(0)-[UITableView:0x7982aa00]>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
Note that I am rotating from portrait to landscape and the error shown are for the portrait orientation! When rotating from landscape to portrait, no debug output/error occurs. Rotating back to landscape causes the same error.
Even with these errors, the view layout appears fine for both portrait and landscape until I show a UIAlertView/Controller. Once an alert is shown, the layout fails and both portrait and landscape layouts are displayed wrong (UITableView disappears, red UIView takes up whole screen, etc). It doesn't matter if the alert is dismissed or still being presented, the layout will fail everytime after the alert.
I created a sample project to reproduce this behavior that can be found here. UI Element outlets are connected in IB. All the code is in the default ViewController class. Any idea why this behavior is occurring or is this a bug in AutoLayout for a simple layout change between orientations? Thanks.
Portrait constraints:
<NSLayoutConstraint:0x7b05cda0 V:|-(0)-[_UILayoutGuide:0x7b0648a0] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05cc30 V:[_UILayoutGuide:0x7b0648a0]-(0)-[UISearchBar:0x7b0e9590]>,
<NSLayoutConstraint:0x7b05cc00 V:[UISearchBar:0x7b0e9590]-(0)-[UITableView:0x7cb4d600]>,
<NSLayoutConstraint:0x7b05cbd0 V:[UITableView:0x7cb4d600]-(0)-[UIView:0x7b0e9210]>,
<NSLayoutConstraint:0x7b05cba0 V:[UIView:0x7b0e9210]-(0)-[UIToolbar:0x7b069f10]>,
<NSLayoutConstraint:0x7b05cb70 V:[UIToolbar:0x7b069f10]-(0)-| (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05ced0 UIView:0x7b0e9210.height == 0.75*UIView:0x7b0e9210.width>,
<NSLayoutConstraint:0x7b05c990 H:|-(0)-[UISearchBar:0x7b0e9590] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c940 H:[UISearchBar:0x7b0e9590]-(0)-| (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c8a0 H:|-(0)-[UIView:0x7b0e9210] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c850 H:[UIView:0x7b0e9210]-(0)-| (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c780 H:|-(0)-[UITableView:0x7cb4d600] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c730 H:[UITableView:0x7cb4d600]-(0)-| (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c6c0 H:|-(0)-[UIToolbar:0x7b069f10] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c670 H:[UIToolbar:0x7b069f10]-(0)-| (Names: '|':UIView:0x7b064990 )>
Landscape constraints:
<NSLayoutConstraint:0x7b05c530 V:|-(0)-[_UILayoutGuide:0x7b0648a0] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c4e0 V:[_UILayoutGuide:0x7b0648a0]-(0)-[UISearchBar:0x7b0e9590]>,
<NSLayoutConstraint:0x7b05c4b0 V:[UISearchBar:0x7b0e9590]-(0)-[UIView:0x7b0e9210]>,
<NSLayoutConstraint:0x7b05c480 V:[UIView:0x7b0e9210]-(0)-[UIToolbar:0x7b069f10]>,
<NSLayoutConstraint:0x7b05c450 V:[UIToolbar:0x7b069f10]-(0)-| (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c290 V:|-(0)-[_UILayoutGuide:0x7b0648a0] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c240 V:[_UILayoutGuide:0x7b0648a0]-(0)-[UISearchBar:0x7b0e9590]>,
<NSLayoutConstraint:0x7b05c210 V:[UISearchBar:0x7b0e9590]-(0)-[UITableView:0x7cb4d600]>,
<NSLayoutConstraint:0x7b05c1e0 V:[UITableView:0x7cb4d600]-(0)-[UIToolbar:0x7b069f10]>,
<NSLayoutConstraint:0x7b05c1b0 V:[UIToolbar:0x7b069f10]-(0)-| (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05bf70 H:|-(0)-[UITableView:0x7cb4d600] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05bf20 H:[UITableView:0x7cb4d600]-(0)-[UIView:0x7b0e9210]>,
<NSLayoutConstraint:0x7b05bef0 H:[UIView:0x7b0e9210]-(0)-| (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05c2f0 UIView:0x7b0e9210.height == 0.75*UIView:0x7b0e9210.width>,
<NSLayoutConstraint:0x7b05be30 H:|-(0)-[UISearchBar:0x7b0e9590] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05bde0 H:[UISearchBar:0x7b0e9590]-(0)-| (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05bd70 H:|-(0)-[UIToolbar:0x7b069f10] (Names: '|':UIView:0x7b064990 )>,
<NSLayoutConstraint:0x7b05bd20 H:[UIToolbar:0x7b069f10]-(0)-| (Names: '|':UIView:0x7b064990 )>
updateViewConstraints
where I swap my constraints...I think that is the problem. Where should I be setting my new constraints? I was going according to this SO post: stackoverflow.com/questions/17772922/… but apparently putting the update code inupdateViewConstraints
isn't right. Right now I can band-aid patch this by callingsetNeedsUpdateConstraints
inviewWillLayoutSubviews
after the constraints have been set a first time, but not too optimal... :( – ansonl