Hidden UIView in CollectionViewCell brokes autolayout - uiview

I have a UICollectionViewCell with autolayout constraints. It works as aspected but my application prints a lot of warnings about unsatisfied constraints:
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:0x7f9e650c50f0 UILabel:0x7f9e650c10c0'Toz Kat Elek >30'.top == UIView:0x7f9e650c0fd0.topMargin - 8>",
"<NSLayoutConstraint:0x7f9e650c51e0 UIView:0x7f9e650c17f0.top == UILabel:0x7f9e650c10c0'Toz Kat Elek >30'.top + 20>",
"<NSLayoutConstraint:0x7f9e650c5280 UIView:0x7f9e650c0fd0.bottomMargin == UIView:0x7f9e650c17f0.bottom - 8>",
"<NSAutoresizingMaskLayoutConstraint:0x7f9e650d8550 h=--& v=--& V:[UIView:0x7f9e650c0fd0(0)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7f9e650c5280 UIView:0x7f9e650c0fd0.bottomMargin == UIView:0x7f9e650c17f0.bottom - 8>
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.
I have tried lots of different combinations to find out the source of the problem. While inspecting my view hierarchy with Debug View Hierarchy I found out that there is an UIView that I didn't add and this UIView causes the warning messages.
So how can get rid of these warning messages?
UPDATE
Here is my view hierarchy:

OK, I have found my answer here: Auto layout constraints issue on iOS7 in UITableViewCell
The problem was about hidden content view of the cell. To get rid of the errors do following before returning the cell in cellForItemAtIndexPath:
cell.contentView.frame = cell.bounds;
cell.contentView.autoresizingMask =
UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleHeight |
UIViewAutoresizingFlexibleBottomMargin;

I think the problem is not about that hidden view. UICollectionViewCell has a contentview like UITableViewCell. The constraint conflict seems about UILabel.
It will be nice if you can take a screenshot of your storyboard.

It's possible to read what's what's happening from the errors: Your label and otherView under it are attached to mysteryView, the label 8 off the top, then 20 separating otherView, and 8 from the bottom of otherView to mysteryView. Very standard. However, an autoresizingMask is setting mysteryView to height of zero. Since it can't satisfy both, it breaks the constraint holding otherView to the bottom. MysteryView goes to zero height (but apparently staying at the top position) and the Label goes 8 off of that, etc., until the otherView hangs attached to nothing at the bottom.
Since mysteryView is attached to your UILabel and otherView, it should be possible to find it and/or break the constraints. Find the label that gets the text "Toz Kat Elek >30" and look at its Size Inspector (the ruler icon in the right-hand panel). Find the constraint that attaches to its top space by -8. There could be more than one, which would be part of the problem. Double click it, and it will be highlighted in the Document Outline to the left of the IB window and the constraints details will appear in the inspector.
If you can only find views you're expecting attached to the UILabel and other elements, examine those views. You might want to clear all constraints using the button at the bottom and start over.
However, if you've found mysteryView and it is indeed a stowaway (apparently with a height of zero) then delete it. The constraints attached to your label and view were working, so you might need to add new ones, attaching the top and bottom to the real top and bottom superview.

have you tried removing the bottom margin contraint for the UIView ?, for what you posted on the warning it says it's removing it to recover from the error. If you did it already can you post the view hierarchy but with the constraints opened? .

Related

Strange autolayout behaviour on collection views

I have an issue with autolayout, the console is reporting problems with an image view I have in a cell:
RefreshCatalogue[31754:16177989] 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:0x7fa98103b740 V:[UIImageView:0x7fa9810375d0]-(0)-| (Names: '|':UIView:0x7fa9810371d0 )>",
"<NSLayoutConstraint:0x7fa98103b7e0 V:|-(0)-[UIImageView:0x7fa9810375d0] (Names: '|':UIView:0x7fa9810371d0 )>",
"<NSLayoutConstraint:0x7fa98103b8d0 UIImageView:0x7fa9810375d0.centerY == UIImageView:0x7fa981037490.centerY>",
"<NSLayoutConstraint:0x7fa98103ba60 UIImageView:0x7fa981037490.top == UIView:0x7fa9810371d0.topMargin + 71>",
"<NSAutoresizingMaskLayoutConstraint:0x7fa980d44a10 h=--& v=--& V:[UIView:0x7fa9810371d0(50)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fa98103b8d0 UIImageView:0x7fa9810375d0.centerY == UIImageView:0x7fa981037490.centerY>
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.
The problem is that if I do:
[self.collectionView reloadItemsAtIndexPaths:#[indexPath]];
Nothing shows even tho the image view seems to have correct frame, the image property is set.
If I reload the entire collection view with:
[self.collectionView reloadData];
The error is still there but the image shows. The code is open here shall anyone be interested in taking a look:
https://github.com/Ridiculous-Innovations/RefreshCatalogue
Also, all the constraints in the story board seem to be in blue. Any idea what might be causing the issue?
Edit: Needless to say that all the elements, including the image view are on the right place (I did debug frames and set random colours) but the image didn't display till refresh ... sometimes the cells don't display at all
You have issue with UIImageView:0x7fa981037490.top == UIView:0x7fa9810371d0.topMargin + 71 and parent frame with 0 height (so imageview height must be negative, but this is not allowed), like right after calling dequeueReusableCell method.
Possible workaround for this case is change priority from 1000 to 999 on the most bottom constraint in nested view (Vertical Space - catalogueHeaderCell - Image View and Vertical Space - catalogueCell - Info View).
In second cell some constraints are disabled. that means that constraints are removed for Any Height Any Width. so when you run app in iphone than that constraints conflict with your current constraints.
so remove that highlighted disable constraints.
Try this it helps me in removing those constraint break in console.
yourCustomCell.contentView.frame = yourCustomCell.bounds;
Views:
UIView:0x7fa9810371d0, let's name it container
UIImageView:0x7fa9810375d0, let's name it image1
UIImageView:0x7fa981037490, let's name it image2.
Not let's inspect the constraints
Container height is 50, specified by autoresizing. The height is probably not specified by your collection view. Most likely this is the size of the cell when it gets created before it gets resized to the size specified by your collection view layout.
image2 is 71 points under the topMargin of container, so it is at least 21 points under bottom edge of the container.
image1 bottom is aligned with the bottom of the container, so it is above the bottom edge of the container.
Now your last constraint centers image1 and image2 vertically so there is obviously a collision.
It's a bit hard to know what you are trying to do but I suppose you should position only image1 relative to the container and the only vertical constraint for image2 should be the ones that centers them vertically.
Too see the errors in Interface Builder, change your cell height to 50, you will see everything broken up. There are just some unnecessary constraints which cause conflict on resizing.
There are also some constraints that are not installed for the current size class. It's possible that you are running the app on a simulator that is of a different size class and has them installed. That means there are even some additional collisions.
check your imageView centerY constrain
delete this constrain...
this problem is occur because of constrain ambiguity. while adding auto layout you have to apply proper auto layout constrain to imageView.
After deleting centreY constrain if there is ambiguity then xcode will again show you same error, again you have to delete ambiguous constrain.
Well the warning message gives a clue to what is wrong.
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fa98103b8d0 UIImageView:0x7fa9810375d0.centerY == UIImageView:0x7fa981037490.centerY>
So to analyse you have two view based objects. One is set to centre its self from top to bottom to the other view (0x7fa9810375d0 to 0x7fa981037490 - these are the views id's)
But also view id 0x7fa981037490 has another constraint,
<NSLayoutConstraint:0x7fa98103ba60 UIImageView:0x7fa981037490.top == UIView:0x7fa9810371d0.topMargin + 71>
Which looks like the top of 0x7fa981037490 is being aligned to the top of view 0x7fa9810371d0 plus 71 points.
I haven't downloaded your project but I'd bet that's where the problem lies. Best guess is the centre.y constraints cannot be satisfied because the align top moves the ImageView into a place that breaks it. Try to look at what you have set in constraints visually in your head. You have aligned to ImageViews and aligned one of those to the edge of another view. How will that break? (is what you should be asking yourself)
Try removing a constraint one at a time and build and run. If the warning goes, thats the one that needs fixing. Yes the view might look weird and you can use Command + Z to undo the deletion of the constraints one by one.
Give it a go. Let me know

iOS 8 Custom Self Sizing Table View : Unable to simultaneously satisfy constraints

In UITableViewController, I am using custom UITableView cell. This cell contains a UIImage control on left side of cell and two UILabels(one is for product name and other is for product description, which can be varying length) to the right of this UIImage. I have added Auto Layout constraints on all three controls. There is no issue in Auto Layout control. However when I run the app, I get the following error messages (one for each row in the table) and a couple of top rows are not as per auto layout constraints, but however when I scroll down and then scroll up, everything is rendered as per the auto layout constraints
Debug Log:
-----------------------------------------------------------------------------
- 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:0x170085ff0 H:[PFImageView:0x14ee1d350(60)]>",
"<NSLayoutConstraint:0x17408a500 PFImageView:0x14ee1d350.leading == UITableViewCellContentView:0x14ee1cdf0.leadingMargin + 7>",
"<NSLayoutConstraint:0x17408a5a0 UITableViewCellContentView:0x14ee1cdf0.trailingMargin == UILabel:0x14ed08580'Naturally Sandstone Slabs'.trailing + 10>",
"<NSLayoutConstraint:0x17408a5f0 H:[PFImageView:0x14ee1d350]-(11)-[UILabel:0x14ed08580'Naturally Sandstone Slabs']>",
"<NSLayoutConstraint:0x17008c6c0 'fittingSizeHTarget' H:[UITableViewCellContentView:0x14ee1cdf0(34)]>" )
Will attempt to recover by breaking constraint <NSLayoutConstraint:0x170085ff0 H:[PFImageView:0x14ee1d350(60)]>
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.
The issue was because i was using a disclosure indicator in the table view. Lowering the priority of label's trailing-to-superview constraint. (I chose 990) fixed the issue.
Below is the link where i get the solution:
ios8 cell constraints break when adding disclosure indicator

Adding a button in dynamic TableViewCell

I have a label of dynamic size in a TableViewCell. I have pinned it to up,down,left and right and set Lines to 0 and it is working fine. Next, I add a button below the label and and pin it to top and left. and fix the width and height. But I am getting an error at runtime
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:0x7fcbc302f600 UILabel:0x7fcbc3034010'Digestion of food in the...'.top == UITableViewCellContentView:0x7fcbc30334a0.topMargin>",
"<NSLayoutConstraint:0x7fcbc3037e30 UITableViewCellContentView:0x7fcbc30334a0.bottomMargin == UILabel:0x7fcbc3034010'Digestion of food in the...'.bottom + 38>",
"<NSLayoutConstraint:0x7fcbc303a920 'UIView-Encapsulated-Layout-Height' V: [UITableViewCellContentView:0x7fcbc30334a0(43.5)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fcbc3037e30
UITableViewCellContentView:0x7fcbc30334a0.bottomMargin ==
UILabel:0x7fcbc3034010'Digestion of food in the...'.bottom + 38>
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. Here is the screenshot of my layout
Which constraint should I remove? I don't think I have added extra constraints
In interface builder check that there are no warnings (the yellow arrow on the side of the vc inspector) and check that the height of the label +the button and the margins don't exceed the cell height.
Also you said you pinned to the top, of what? The container or the label?
Use these constraint for as per your requirements:
OR
Follow these links Autolayout or Autolayout programatically
(OR)
For some reason, Xcode generates own default set of auto layout constraints on a NIB at build time. This is why I couldn't add any more manual constraints, because they were conflicting with the automatically added ones.
I resolved this the following way:
Open up the Storyboard view controller you're handling.
Select the view controller and select Editor > Resolve Auto Layout Issues > All Views in [ ] View Controller > Add Missing Constraints from the menu:
This will ensure that no additional build time constraints are created and all the constraints are now visible.-->Select all the constraints from your view controller:
This will ensure that no additional build time constraints are created and all the constraints are now visible.-->Check from the right pane the following check box: Placeholder - Remove at build time:
(This will ensure that no additional build time constraints are created and all the constraints are now visible.)
Now you can add all the auto layout constraints manually in the code.
you will have to provide some more info than that regarding the values you set in auto layout like the distance of the UILabel from top margin,down,left etc.
The problem might be that you specified the UIButton to be from top margin , it should be with respect to your UILabel as its below it so set the UIButton's vertical spacing property to the UILabel this makes sure the UIButton is placed below it.

What is the correct way to use UIScrollView?

I tried to setup a simple view which displays a text-only article with a headline. Here are the steps that I've done:
Create View Controller with its .xib file,
Create UIScrollView and places a UIView directly as the content wrapper,
Set the constraints [scrollview]-0-[superview] in top, bottom, leading, and trailing.
Set the constraints [content wrapper]-0-[scroll view] in top, bottom, leading, and trailing.
Set Width and Height to content wrapper as placeholder.
Add Label and UITextView as content wrapper's subviews.
Add constraints to the subviews.
Following this tutorial, I programmatically set content wrapper's leading = scrollview's superview left,
... And content wrapper's trailing = scrollview's superview right.
When I ran the code, it shows everything in place perfectly; The UIScrollView scrolls, margins are properly set, etc.
However, Xcode throws an exception:
2015-02-05 18:06:58.230 ScrollViewApp[5353:180401] 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:0x7ff9fa49a3f0 H:[UIView:0x7ff9fa571560(600)]>",
"<NSLayoutConstraint:0x7ff9fa49b1a0 H:|-(0)-[UIView:0x7ff9fa571560] (Names: '|':UIScrollView:0x7ff9fa49a910 )>",
"<NSLayoutConstraint:0x7ff9fa49ce00 H:|-(0)-[UIScrollView:0x7ff9fa49a910] (Names: '|':UIView:0x7ff9fa49a840 )>",
"<NSLayoutConstraint:0x7ff9fa61c050 UIView:0x7ff9fa571560.right == UIView:0x7ff9fa49a840.trailing>",
"<NSLayoutConstraint:0x7ff9fa580970 'UIView-Encapsulated-Layout-Width' H:[UIView:0x7ff9fa49a840(375)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7ff9fa49a3f0 H:[UIView:0x7ff9fa571560(600)]>
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.
After further googling, I found out that I can dismiss the warning by setting content wrapper's width (see step 5 above) priority to low; however it breaks the layout in interface builder. Take a look:
Compared to when it's set to High priority:
I know that in the end it makes no difference because it's both working as expected.. But I'm kind of curious as to why these things happen..
I'm trying to understand how UIScrollView works, but maybe I'm misunderstanding something; so, what is the proper way for setting up UIScrollView to work as expected?
Try to add a center horizontally constraint from your content wrapper to your scroll view.
To be honest, I really don't know why that works, i figured this one out by trial an error. If you want your view to be compatible different screen sizes, remove the width constraint of the content wrapper.
Hope it helped.
you can use scrollview like this. Add scrollview in design. Give it's left, top, right, bottom constraints in design. Add your subviews in scrollview. Add proper constraints for them. There is no need to add constraints in code. In viewDidLayoutSubviews set your scrollview's content size.
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
CGRect boundsOfSelf = self.view.bounds;
scrollView.frame = boundsOfSelf;
[scrollView setContentSize: boundsOfSelf.size];
}

AutoLayout issue in dynamic UITableViewCell's subviews

While I seem to have taken the gist of setting the view constraints on UIViews of storyboards, I just can't seem to figure out why constraints are not properly working in a dynamic cell prototype ContentView's subviews.
The cell is pretty simple: A UIImageView background that fills the entire cell, in front of it another UIImage and a label as following:
The background UIImageView has the following 4 constraints:
0 fixed to: trail, bottom, top and leading space to superview
The profile picture image has a fixed width and height and a constant 13pts space to leading superview and has a vertical center in container
The Label has an 8pt leading space to the profile pic and trailing space to superview, and has a vertical center in container.
This is what I am getting:
Did I miss something? I researched the issue but no answer solved the issue. However, I tried adding the following lines in the cellForRowAtIndexPath after loading the cell:
cell.setNeedsUpdateConstraints()
cell.updateConstraintsIfNeeded()
which gave the following errors at runtime:
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:0x7fe5434852c0 H:[UIImageView:0x7fe543484450(75)]",
"NSLayoutConstraint:0x7fe5436c5cd0 H:|-(12)-[UIImageView:0x7fe543484450] (Names: '|':UITableViewCellContentView:0x7fe5434820f0 )",
"NSLayoutConstraint:0x7fe5436c34e0 H:[UILabel:0x7fe543487430'Joseph']-(8)-| (Names: '|':UITableViewCellContentView:0x7fe5434820f0 )",
"NSLayoutConstraint:0x7fe5436bcca0 H:[UIImageView:0x7fe543484450]-(8)-[UILabel:0x7fe543487430'Joseph']",
"NSLayoutConstraint:0x7fe5436cb110 'UIView-Encapsulated-Layout-Width' H:[UITableViewCellContentView:0x7fe5434820f0(0)]"
)
Will attempt to recover by breaking constraint
NSLayoutConstraint:0x7fe5434852c0 H:[UIImageView:0x7fe543484450(75)]
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.
Any clues?
Well, problem is priorities.
You have background image, which has some size according to image you put into it and than there is a profile picture with fixed height and constant space 13pts top and bottom.
Table may have separator and that one is adding extra space.
So advice: lower for example bottom 13pts constrains from 1000 to 750. That should remove warning.

Resources