CollectionViewCell, custom cell, autolayout constraints with multiline - ios

I have storyboard with custom cell, I have 3 views on my custom cell but one of the view causing a problem, UILabel with 2 line support. I use W:Any-H:Any and create a constraits to a label like this (now, to elimiate all the issues - i'm connecting it to superviews, not to views nearest, but error still occurs):
Leading Space to Superview
Trailing Space to Superview
Top Space to Superview
So it looks like this:
If I remove constraints from this view I'm not getting error so error must be from this.
And then i get constraints error:
(
"<NSLayoutConstraint:0x7fe1d3df4e80 UILabel:0x7fe1d3df7730'Autos, Roller, Fahrr\U00e4der,...'.trailing == UIView:0x7fe1d7a33140.trailingMargin>",
"<NSLayoutConstraint:0x7fe1d3df4ed0 H:|-(70)-[UILabel:0x7fe1d3df7730'Autos, Roller, Fahrr\U00e4der,...'] (Names: '|':UIView:0x7fe1d7a33140 )>",
"<NSAutoresizingMaskLayoutConstraint:0x7fe1d3dbb1c0 h=--& v=--& H:[UIView:0x7fe1d7a33140(50)]>"
)
What's the problem and how to fix it?

Changing the priority of Trailing Space to 999 is a simple workaround, but I cannot explain how this fixes that.
It appears that Trailing Space (1st constraint in the error) constraint conflicts with constraint which is translated from the autoresizing mask of contentView (3rd constraint) and this workaround resolves it.

Related

Dynamic Height Table Cell with Autolayout and UITableAutomaticDimension (Dynamic UILabel + several UIImageViews)

I looked through the articles related with dynamic table cell and auto layout for 3 days and not working so far.
Below is the table cell what I wanted. Here the main issue is UILabel for post text and UIImages.
Here is the hierarchy of the UI elements.
- Content View
+ ...
+ UILabel for text - dynamic height
+ UIView - image view container
* UIImageView
* UIImageView
* ....
Label has line break mode wrap text and lines set to 0.
Label and the container view has constraints for top, bottom, leading and trailing. ImageViews are added at runtime and has constraint for top, leading, trailing, bottom and height constraints.
First image view has top constraint to container view and last image view has bottom constraint to container view and others has top constraint to upper image view.
When the table is first loaded (cells has different image counts), it looks fine, but when I scroll up and down, constraints are breaking in some cells and images are overlapping inside cells.
Here is the error output:
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.
"<NSLayoutConstraint:0x17428aaf0 V:|-(0)-[UIImageView:0x14be77ed0] (active, names: '|':UIView:0x14be75b20 )>",
"<NSLayoutConstraint:0x17428a6e0 UIImageView:0x14be77ed0.height == 160 (active)>",
"<NSLayoutConstraint:0x17428acd0 UIImageView:0x14be77ed0.bottom == UIView:0x14be75b20.bottom (active)>",
"<NSLayoutConstraint:0x174289650 V:|-(0)-[UIImageView:0x14be43ce0] (active, names: '|':UIView:0x14be75b20 )>",
"<NSLayoutConstraint:0x17428bb80 UIImageView:0x14be43ce0.height == 160 (active)>",
"<NSLayoutConstraint:0x17428be50 V:[UIImageView:0x14be43ce0]-(10)-[UIImageView:0x14be74b10] (active)>",
"<NSLayoutConstraint:0x17428bfe0 UIImageView:0x14be74b10.height == 160 (active)>",
"<NSLayoutConstraint:0x17428c080 UIImageView:0x14be74b10.bottom == UIView:0x14be75b20.bottom (active)>"
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x17428be50 V:[UIImageView:0x14be43ce0]-(10)-[UIImageView:0x14be74b10] (active)>
Please help me with this issue. Thank you.
To make sure the stack view does not contain old images when the cell is dequeued, you need to clean it in prepareForReuse():
override func prepareForReuse() {
super.prepareForReuse()
stack.arrangedSubviews.forEach {
stack.removeArrangedSubview($0)
$0.removeFromSuperview()
}
}
I would suggest not to give your images height, instead add a vertical stackview into your container view and add all your images in there. make sure they have content mode set to aspect fit and the stackview should take care of the rest. don't forget to constrain the stackview to the bottom of the label and the bottom of the cell, so it knows how much space it has. it will take care of your images by itself
ImageViews are added at runtime and has constraint for top, leading, trailing, bottom and height constraints.
This is your error message. Remove either height or one of the constraint that you choose either bottom or top contraint. You can not have all 4 sides constrained and add a height constrant to that.
Sidenote:
That goes same for width, if you set a width constraint, you can not have both sides leading/trailing constrained at the same time.
EDIT:
Also, easier off with using a UIStackView as suggested in the comments sections.

Unable to simultaneously satisfy constraints When trying to load xib file

I am trying to implement the UITableView using xib file
But when I run the app I am getting the following error & the xib is properly in small screen like iPhone4s
it works fine in larger display size.
Screenshot of xib
Any help will be appreciated
Error
2016-12-14 17:12:41.826 FoodStrock[5776:1761262] 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.
(
"<NSLayoutConstraint:0x7fcc2a6dfac0 V:[UIImageView:0x7fcc2a6e1010(63)]>",
"<NSLayoutConstraint:0x7fcc2a617530 V:[UIImageView:0x7fcc2a6e1010]-(8)-| (Names: '|':UITableViewCellContentView:0x7fcc2a6e1270 )>",
"<NSLayoutConstraint:0x7fcc2a6cc3b0 V:|-(9)-[UIImageView:0x7fcc2a6e1010] (Names: '|':UITableViewCellContentView:0x7fcc2a6e1270 )>",
"<NSLayoutConstraint:0x7fcc2a4955a0 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7fcc2a6e1270(59.6667)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fcc2a6dfac0 V:[UIImageView:0x7fcc2a6e1010(63)]>
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.
2016-12-14 17:12:41.827 FoodStrock[5776:1761262] 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.
(
"<NSLayoutConstraint:0x7fcc2a6a69d0 V:[UILabel:0x7fcc2a6e1670'Address'(63)]>",
"<NSLayoutConstraint:0x7fcc2a693820 UILabel:0x7fcc2a6e1670'Address'.bottom == UITableViewCellContentView:0x7fcc2a6e1270.bottomMargin>",
"<NSLayoutConstraint:0x7fcc2a6e0c00 UILabel:0x7fcc2a6e1670'Address'.top == UITableViewCellContentView:0x7fcc2a6e1270.topMargin + 1>",
"<NSLayoutConstraint:0x7fcc2a4955a0 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7fcc2a6e1270(59.6667)]>"
)
Put your UIImageView , UILabel, UIButton in single UIView(says mainView). Now mainView constraints will be leading, trailing, top bottom from the xib view(superView). Now constraints of UIImageView , UILabel, UIButton is according to your requirement w.r.t. mainView.
NOTE: Give constraints to the UIComponents as minimal as possible but keep mind about it full fills your requirement. Like here, give constraints like this:
UIImage : top, bottom , Leading wrt mainView and constant width or you can give horizontally center to container, leading, height, width.
UIButton : top, bottom, trailing wrt mainView and constant width or you can give horizontally center to container, leading, height, width.
UILabel : leading trailing and horizontally centre to container is enough but you can give height also.
UILabel can automatically take height and width according to the text font size you just need to specify x and y coordinates.

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!

Resources