Constraints are not working as expected in landscape orientation - ios

I test very simple layout with autolayout use storyboard only(no code any where)
i dropped the Button object wAny, hAny and then switch size class to wCompact, hAny
and add Constraint 'Center Horizontally in Container' & 'Top Space to Top layout guide'.
next i switch size class to wAny, hCompact and add constraint 'Center Vertically in Container' & 'Trailling space to Container Margin' and width,height constraint
that's all i added constraints, there is no warning and error in storyboard.
i expected as top centered button in portrait and right centered in landscape.
portrait is running normally but preview and simulator show me wrong result when i was change orientation with error log.
like this
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:0x7a065db0 V:[_UILayoutGuide:0x7a067440(0)]>",
"<_UILayoutSupportConstraint:0x7a068010 V:|-(0)-[_UILayoutGuide:0x7a067440] (Names: '|':UIView:0x7a0661d0 )>",
"<NSLayoutConstraint:0x7a0680b0 V:[_UILayoutGuide:0x7a067440]-(20)-[UIButton:0x7a066740'Button']>",
"<NSLayoutConstraint:0x7a06d9e0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7a0661d0(320)]>",
"<NSLayoutConstraint:0x7a068050 UIView:0x7a0661d0.centerY == UIButton:0x7a066740'Button'.centerY>",
"<NSLayoutConstraint:0x7a0680e0 V:[UIButton:0x7a066740'Button'(30)]>"
)
Will attempt to recover by breaking constraint "<NSLayoutConstraint:0x7a0680e0 V:[UIButton:0x7a066740'Button'(30)]>
and button fills width and height its container view.
i can't figure out what i did wrong?
am i missing something important about autolayout(with orientation)?
plz help me
(sorry for my bad english. i'm non english native speaker-)

Your problem is that wCompact|hAny is for iPhones in portrait or landscape. So you end up with conflicting constraints in landscape because all of your constraints apply. You should use wCompact|hRegular for iPhones in portrait.

Related

Why does my storyboard keep resizing my views

I have a UIStoryBoard with a ViewController that contains a UITableView. I added Views above and below the UITableView to act as a header/footer that will scroll with the UITableView, that is all working appropriately. The problem is when I resize the header/footer Views, they show up correctly in the preview, but they are not the correct size in the app.
Here is how it looks in StoryBoard:
And when I run it on the app the top View takes up the entire screen. But here is the weird thing, if I close Xcode and reopen it both the header and footer views have a height of 568, which I'm assuming is why they look so huge in the app. Why is Xcode resizing these views? I have tried removing all constraints but it doesn't make any difference.
I actually removed the ViewController entirely from the storyboard and remade it and it is still doing this same behavior.
Here is what it looks like after I restart Xcode:
EDIT
Getting this output in the console:
2015-05-06 14:16:43.214 FitHub[16063:674572] 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)
(
"<NSLayoutConstraint:0x7fe46b2ac6a0 V:[UILabel:0x7fe46b2ac6f0'Settings']-(16)-| (Names: '|':UIView:0x7fe46b13a7a0 )>",
"<NSLayoutConstraint:0x7fe46b2ad6b0 V:[UIImageView:0x7fe46b2ad700]-(13)-[UILabel:0x7fe46b2ac6f0'Settings']>",
"<NSLayoutConstraint:0x7fe46b2b2360 V:|-(16)-[UIImageView:0x7fe46b2ad700] (Names: '|':UIView:0x7fe46b13a7a0 )>",
"<NSLayoutConstraint:0x7fe46b2b22e0 V:[UIImageView:0x7fe46b2ad700(35)]>",
"<NSLayoutConstraint:0x7fe46b2b2030 V:[UILabel:0x7fe46b2ac6f0'Settings'(30)]>",
"<NSAutoresizingMaskLayoutConstraint:0x7fe46b2c9360 h=--& v=--& V:[UIView:0x7fe46b13a7a0(568)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fe46b2b22e0 V:[UIImageView:0x7fe46b2ad700(35)]>
Thanks in advance.
Ok, so I have been working in the size class of wCompact hRegular, because we are only developing for iPhones in portrait mode. I had to change the size class to wAny hAny and then resize the frame height from 568 to 110.
I am curious though, is there a reason why I had to do it for this specific controller and not for any other ones?

Contraints greyed-out in Xcode

I am trying to debug+understand autolayout constraints and I notice that when debugging the view with xcode (using the cool layer thing) I noticed that on one element in the view the constraints look like this
and the view is indeed ignoring these constraints.
All constraints have the same priority (1000) since I want them all. All constraints were made with interface builder and not through code, and there are not warning or conflicts in IB.
But in runtime I do see this
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)
(
"<NSLayoutConstraint:0x79684f10 V:[UIImageView:0x79686800(>=160)]>",
"<NSLayoutConstraint:0x7968a310 V:[UIImageView:0x79686800]-(130.5)-| (Names: '|':UIView:0x79686790 )>",
"<NSLayoutConstraint:0x7968a340 V:|-(0)-[UIImageView:0x79686800] (Names: '|':UIView:0x79686790 )>",
"<NSLayoutConstraint:0x796997b0 'UIView-Encapsulated-Layout-Height' V:[CoverCell:0x79686570(192)]>",
"<NSAutoresizingMaskLayoutConstraint:0x7969cd30 h=-&- v=-&- UIView:0x79686790.height == CoverCell:0x79686570.height>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x79684f10 V:[UIImageView:0x79686800(>=160)]>
So from this I understand that some rules conflict, but I'm not sure how to read this
the >=160 is a rule on the UIImageView so it would have height of atleast 160 and 130.5 is the bottom padding of the imageview (so when using systemLayoutSizeFittingSize:UILayoutFittingCompressedSize the height won't be 0. So the minimum height for the entire cell is 160+130.5)
The rest of the error I don't understand.
What is wrong with the constraints and why do constraint conflicts occur in runtime and not in IB?
XCode 6 now supports different layouts. This greyed out constraints exist in Compact Width | Any Height layout, for example, but you currently editing Any Width | Any Height.
More detailed:
Storyboard View Elements Greyed Out
It depends. If you don't use size classes the grey ones are the removed ones. And you need to remove them second time. No matter how stupid it sounds.
If you use size classes, it means that your current size class is different than for greyed constraint. (however the first scenario is also possible...)
In your case it looks like this is the first case. You need to remove greyed constraints once again.

UIScrolView auto layout contraints breaking on device rotation

I'm having a rather annoying problem with auto-layout constraints set on a UIScrollView and its sub views. When the device orientation changes, it breaks a constraint with the following warning:
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)
(
"<NSLayoutConstraint:0x7a1b1830 V:[UIView:0x7a1b0520(768)]>",
"<NSLayoutConstraint:0x7a1c5990 V:[UIView:0x7a1bcf50(1024)]>",
"<NSLayoutConstraint:0x7a17aa70 V:|-(0)-[UIView:0x7a1b0520] (Names: '|':UIScrollView:0x7a176520 )>",
"<NSLayoutConstraint:0x7a1c49c0 V:[UIView:0x7a1b0520]-(0)-| (Names: '|':UIScrollView:0x7a176520 )>",
"<NSLayoutConstraint:0x7a172620 V:[UIView:0x7a1bcf50]-(0)-| (Names: '|':UIScrollView:0x7a176520 )>",
"<NSLayoutConstraint:0x7a172650 V:|-(0)-[UIView:0x7a1bcf50] (Names: '|':UIScrollView:0x7a176520 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7a1c5990 V:[UIView:0x7a1bcf50(1024)]>
I've set up a scroll view in my storyboard and it contains two containers as sub views. The scroll view itself is pinned on all four sides to the superview (Editor/Pin/Leading-, Trailing-, Top-, Bottom-Space to superview). The two containers have their edges pinned to the scroll view with Auto-Layout constraints but the width & height of both is set as fixed on the storyboard, see att. image:
The width and height of the two containers gets updated via code, once initially in viewDidLoad() and whenever the devices orientation changes, in didRotateFromInterfaceOrientation():
_primaryWidth.constant = view.bounds.size.width
_primaryHeight.constant = view.bounds.size.height
_secondaryWidth.constant = _primaryWidth.constant - 200
_secondaryHeight.constant = _primaryHeight.constant
This is when the above warning appears and the constraints break and the layout goes overboard. Can somebody tell me why this is happening and how to fix it?
(Note the minus 200. This is because the right container should have a smaller width. But it doesn't affect the issue. The constraints break even without this.)
You have constraints which pin the edges of the scroll view to the edges of the screen which works in both portrait and landscape.You also have a constraint which sets the height of one of your views to 1024.
In portrait that all works, but the moment you rotate to landscape you can't have something be 1024 height pinned to the edge of the screen on top an bottom because the screen is only 768 in height. One has to go and you can see which one gets the axe.
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7a1c5990 V:[UIView:0x7a1bcf50(1024)]>
Remove the height constraints and you'll be fine. Why would you need them anyway? You want the views to pin to the edge of the screen/superview regardless of the size your given. Non-arbitrary values will also allow you to carry the same code/layout to other devices or as sub-views without layout changes.

Autolayout contraint error

So this autolayout error. Which I know why it is there but I am not sure how can I fix it. As with error its clear that its not able to resolve the constraints.
In portrait mode all 47 episode are listed and can be scrolled to. But in landscape mode it cant, which is clear as height of table is not changing thats way its is still down there but can't scroll to it.
So this is how I have setup.
Where as view controller has two view which works as placeholder upper is of for iAds and lower is holding table view. Idea was behind this. if ad is not loaded I will set height of View to zero which holds iADBanner. So that Table view takes up all space. (Got this idea from Ray Wenderlich's app level me up.) I was struggling with auto layout initially but I made it right so that view are taking up all width when sim goes to portrait mode. but somehow I am not able to fix the height of view which holds tableView.
Below are the screenshot of constraints.
I tried to be as descriptive as I can. but I am looking for more than just answer. I want to get to know this completely so that I will most likely won't have problem in future. I have finished raywenderlich tutorial already. So Any other pointer would be very much appreciate along with the answer.
2014-07-30 21:40:37.326 Test[85608:60b] 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) (
"<NSLayoutConstraint:0xa5afbc0 UIView:0xa69b7d0.width == 0.682303*UIView:0xa69b830.height>",
"<NSLayoutConstraint:0xa5afc80 V:|-(50)-[UIView:0xa69b830] (Names: '|':UIView:0xa69b7d0 )>",
"<NSLayoutConstraint:0xa5afdc0 V:[UIView:0xa69b830]-(0)-[_UILayoutGuide:0xa5a8410]>",
"<_UILayoutSupportConstraint:0xa5a7d20 V:[_UILayoutGuide:0xa5a8410(0)]>",
"<_UILayoutSupportConstraint:0xa5af490 _UILayoutGuide:0xa5a8410.bottom == UIView:0xa69b7d0.bottom>",
"<NSAutoresizingMaskLayoutConstraint:0xa792d10 h=--& v=--& H:[UIView:0xa69b7d0(480)]>",
"<NSAutoresizingMaskLayoutConstraint:0xa792dd0 h=--& v=--& V:[UIView:0xa69b7d0(271)]>" )
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0xa5afdc0 V:[UIView:0xa69b830]-(0)-[_UILayoutGuide:0xa5a8410]>
Break on objc_exception_throw to catch this in the debugger. The
methods in the UIConstraintBasedLayoutDebugging category on UIView
listed in <UIKit/UIView.h> may also be helpful.
The list of constraints in the error log is the key to understanding this type of problem. What you want to do is look at it carefully to correlate which lines refer to which constraints in your code/ui builder, and which hexadecimal address refers to which view.
V:[UIView:0xa69b830]-(0)-[_UILayoutGuide:0xa5a8410] is a constraint setting the bottom of a UIView to a layout guide, so most likely that's the last constraint in your screenshot "Vertical Space - Bottom layout guide - TableVi..." (presumably that's TableViewHolder truncated). That means UIView:0xa69b830 is your TableViewHolder.
V:|-(50)-[UIView:0xa69b830] (Names: '|':UIView:0xa69b7d0 ) is the constraint tying the top of TableViewHolder 50px from its superview, which must be UIView:0xa69b7d0.
UIView:0xa69b7d0.width == 0.682303*UIView:0xa69b830.height looks like an aspect ratio constraint between the superview width and the TableViewHolder height.
h=--& v=--& H:[UIView:0xa69b7d0(480)] and h=--& v=--& V:[UIView:0xa69b7d0(271)] are constraints on the superview that's derived from its autoresizingMask, where the width=480px, height=271px, and their top/left/width/height are fixed (based on h=--& v=--&). This is sort of the standard setup for the root view of a view controller — it's dimensions are managed manually by the view controller to fill the screen.
So once you have all that, you can see what the problem is: the superview has fixed dimensions 480x271. Meanwhile, TableViewHolder's height is being dictated by multiple conflicting constraints:
#1 and #2 are trying to stretch it vertically to fill its superview with a 50px margin at the top, so height = 271-50 = 221px.
#3 is trying to set the height as a ratio of the superview's width: height = 480/0.6823 = 703.5px
221 != 730.5!
Something's gotta give, and the OS just happened to pick #1, so the bottom of TableViewHolder extends past the bottom of the layout guide, making it stick out past the edge of the screen and inaccessible.
Your fix will likely involve getting rid of that aspect ratio constraint, but there might be other issues that appear once you fix that. Good luck!

How to specify square (actually round) avatar in Xcode 5 storyboard with Auto Layout on?

Is there a way in Xcode 5 to specify that an image view should be square - both in portrait and landscape orientations?
Is it possible in the Storyboard (with "Auto Layout" on) or do I have to do it in the view controller source code?
I have prepared a simple test app for iPhone. On the top it should display a round user avatar, so I am using SDWebImage and NZCircularImageView through CocoaPods.
So the avatar bounds should be square. When I set its width and height to 280 through constraints (here fullscreen),
this works - but in portrait mode only:
While in the landscape orientation this of course fails:
So I wonder if there is a trick to make it work (the avatar be perfectly round) in landscape orientation as well?
UPDATE:
When rotating to landscape, there is this warning:
2014-04-26 17:57:00.967 MyPhone[1220:60b] 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)
(
"<NSLayoutConstraint:0x8c82e10 H:[NZCircularImageView:0x8c82a70(280)]>",
"<NSLayoutConstraint:0x8c87640 H:[NZCircularImageView:0x8c82a70]-(20)-| (Names: '|':UIView:0x8c86870 )>",
"<NSLayoutConstraint:0x8c876a0 H:|-(20)-[NZCircularImageView:0x8c82a70] (Names: '|':UIView:0x8c86870 )>",
"<NSAutoresizingMaskLayoutConstraint:0x8d48410 h=--& v=--& V:[UIView:0x8c86870(480)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x8c82e10 H:[NZCircularImageView:0x8c82a70(280)]>
Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
So as suggested by Jesse I have removed the redundant constraints (to the left and right of the image view) and added horizontal alignment to keep the image view in the middle.
However I still don't know how to shrink the image view when in landscape mode - so that it doesn't overlap the 2 labels and the button on the bottom of the view:
What I am trying to achieve:
Have a round (i.e. its bounds should be square) avatar on the top
The 2 labels and the button should always be visible at the bottom
The avatar should grow to take any available space
UPDATE 2:
I've added ratio 1:1 constraint and also 20px from the image view bottom to the first name label (here fullscreen):
The landscape is ok now, exactly as I wanted it to be:
But the portrait mode is not ok: the width does not fit:
And it doesn't look good if I just add the left/right constraints:
You may pin width of your image to 280px and then ctrl drag from image view to itself and choose aspect ratio constraint with multiplier 1. This will make height of your image view match to it's width
Here's how I have done it:
Set the ratio to be 1:1.
Set horizontal right and left spacing as a >= constraint.
Set top-space as a fixed value
Set vertical spacing from the image to first label as >= constraint
Make the label fixed on the bottom
Center the image horizontally.
And heres a screenshot of my constraints, note that the fixed width is removed at build time. This is only to make IB make the square something other than 0px.
Your view is over-constrainted; you have set both the width and constraints to the left and right edges of the superview. This can't be satisfied in landscape, so you'll have to remove some constraints. (You're probably getting an error about this in the log?)
I'm not sure exactly what effect you want, but you could try removing the left and right edge constraints and instead adding a horizontal centering constraint. This will keep you view the same size in both orientations. If you want something different, try adding some more details or a mock up of the landscape layout you want.

Resources