Ondrej Rafaj
Ondrej Rafaj

Reputation: 4417

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

Upvotes: 13

Views: 1340

Answers (6)

Bevan
Bevan

Reputation: 342

check your imageView centerY constrain

enter image description here

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.

Upvotes: 0

Sulthan
Sulthan

Reputation: 130200

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.

Upvotes: 0

Bhuvan Bhatt
Bhuvan Bhatt

Reputation: 3496

Try this it helps me in removing those constraint break in console.

yourCustomCell.contentView.frame = yourCustomCell.bounds;  

Upvotes: 0

pcholberg
pcholberg

Reputation: 520

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).

Upvotes: 2

Pooja Patel
Pooja Patel

Reputation: 636

enter image description here

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.

Upvotes: 0

latenitecoder
latenitecoder

Reputation: 756

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

Upvotes: -1

Related Questions