Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UICollectionView Cell + UiLabel with AutoLayout

I'm trying to pin an UILabel to it's parent cell. I added four constraints (top, leading, trailing, bottom) which works fine on iOS 8.0 but not on iOS 7.X. Please see image below:

[Click here for full size]

enter image description here

What am I doing wrong? Please advise!

EDIT #1

It seems it's only broken since Xcode 6 GM. My approach was working fine in Xcode 6 beta 7.

Moreover, if I decrease the inner view's width, it throws the following warning:

2014-09-10 19:58:28.109 Test[57827: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:0x799573a0 H:|-(8)-[UIView:0x798a86e0]   (Names: '|':UIView:0x798ae5d0 )>",
    "<NSLayoutConstraint:0x799573d0 H:[UIView:0x798a86e0]-(43)-|   (Names: '|':UIView:0x798ae5d0 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x798a8b00 h=--& v=--& H:[UIView:0x798ae5d0(50)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x799573d0 H:[UIView:0x798a86e0]-(43)-|   (Names: '|':UIView:0x798ae5d0 )>

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.
like image 333
Attila H Avatar asked Sep 10 '14 16:09

Attila H


4 Answers

Overriding the custom cell's layoutSubviews is a possible workaround:

override func layoutSubviews() {
    contentView.frame = bounds
    super.layoutSubviews()
}
like image 140
Attila H Avatar answered Oct 21 '22 20:10

Attila H


UIView:0x798ae5d0 is the contentView of the CollectionViewCell. Somehow at a certain moment it uses the UICollectionViewCells defaultSize, which is (50.0, 50.0).

<NSAutoresizingMaskLayoutConstraint:0x798a8b00 h=--& v=--& H:[UIView:0x798ae5d0(50)]>

As your horizontal margins 8 + 43 = 51 are bigger than the contentView (50) it is impossible to satisfy the layout.

<NSLayoutConstraint:0x799573a0 H:|-(8)-[UIView:0x798a86e0]   (Names: '|':UIView:0x798ae5d0 )>
<NSLayoutConstraint:0x799573d0 H:[UIView:0x798a86e0]-(43)-|  (Names: '|':UIView:0x798ae5d0 )>

One can make the layout more flexible, so that it also works on a (50.0, 50.0) size. In your case by changing equal 43 to <= 43 or by reducing a priority of 1000 to 750 or 999.

like image 29
coco Avatar answered Oct 21 '22 19:10

coco


The problem is that your custom view (UILabel) has constraints, which conflict with cell's (or better cell's contentView's) constraints. The cell's NSAutoresizingMaskLayoutConstraint are created automatically from what you set in UICollectionView properties in xib (or storyboard) as Cell Size. I have solved my similar problem (*) by explicitly setting

- (void)awakeFromNib {

    [super awakeFromNib];

    self.contentView.translatesAutoresizingMaskIntoConstraints = NO;
}

in my custom UICollectionViewCell subclass. This gets rid of cell size constraint set in Storyboard.

(*) Disclaimer: My collectionView has self sizing cells based on their content view, which is defined by autolayout. I had warnings about conflicting constraints of my content autolayout, and explicit size in Storyboard. This helped me to get rid of those warnings.

like image 35
Vilém Kurz Avatar answered Oct 21 '22 19:10

Vilém Kurz


Instead of giving four constraints (top, leading, trailing, bottom). Try top, leading, width and height. It should work.

like image 30
GameBegins Avatar answered Oct 21 '22 19:10

GameBegins