Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UICollectionViewCell Auto Layout

I have made up a simple custom UICollectionViewCell in my storyboard, I also did this programatically with identical results.

It has a singular UIImageView and two UILabels, like so:

          <--UIIMAGEVIEW-->          <--UILABEL-------->
|-(10px)- |               | -(10px)-                     -(10px)-|
          <--------------->          <--UILABEL-------->

The image is sat on the left, then to the right of it are two labels above and below each other.

Each are spaced out with 10 pixel gaps, and all centred on the cells Y axis. The labels then have a constant to offset them from the centre (up and down).

The image has fixed height and width of 44px and the labels have a fixed height of 20px (with flexible width).

The constraints work as expected and never break the app, but they always spit out this annoying console log info below, as they are apparently breaking.

If I add this line to my UICollectionViewCell subclass, the constraints no longer break and spit out console errors, but they are totally broken onscreen.

[self.contentView setTranslatesAutoresizingMaskIntoConstraints:NO];

Any clues? It seems so illogical!

Here is the console error code:

2014-10-25 18:28:14.273 Air Plan[1579:580797] 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:0x17009edc0 H:[UIImageView:0x1701f7d00(44)]>",
    "<NSLayoutConstraint:0x17009f130 H:|-(10)-[UIImageView:0x1701f7d00]   (Names: '|':UIView:0x170183810 )>",
    "<NSLayoutConstraint:0x17009f270 H:[UIImageView:0x1701f7d00]-(10)-[UILabel:0x155e59970'detailLbl']>",
    "<NSLayoutConstraint:0x17009f310 H:[UILabel:0x155e59970'detailLbl']-(10)-|   (Names: '|':UIView:0x170183810 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x17409eff0 h=--& v=--& H:[UIView:0x170183810(50)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x17009edc0 H:[UIImageView:0x1701f7d00(44)]>

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.
2014-10-25 18:28:14.276 Air Plan[1579:580797] 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:0x17009fcc0 H:[UIImageView:0x1701fa800(44)]>",
    "<NSLayoutConstraint:0x17009ff40 H:|-(10)-[UIImageView:0x1701fa800]   (Names: '|':UIView:0x170180a90 )>",
    "<NSLayoutConstraint:0x1702800a0 H:[UIImageView:0x1701fa800]-(10)-[UILabel:0x155e5b440'detailLbl']>",
    "<NSLayoutConstraint:0x170280140 H:[UILabel:0x155e5b440'detailLbl']-(10)-|   (Names: '|':UIView:0x170180a90 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x17409ea00 h=--& v=--& H:[UIView:0x170180a90(50)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x17009fcc0 H:[UIImageView:0x1701fa800(44)]>

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.
2014-10-25 18:28:14.278 Air Plan[1579:580797] 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:0x170280a00 H:[UIImageView:0x1701fab00(44)]>",
    "<NSLayoutConstraint:0x170280c80 H:|-(10)-[UIImageView:0x1701fab00]   (Names: '|':UIView:0x1701822f0 )>",
    "<NSLayoutConstraint:0x170280dc0 H:[UIImageView:0x1701fab00]-(10)-[UILabel:0x155e5cd10'detailLbl']>",
    "<NSLayoutConstraint:0x170280e60 H:[UILabel:0x155e5cd10'detailLbl']-(10)-|   (Names: '|':UIView:0x1701822f0 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x17409f180 h=--& v=--& H:[UIView:0x1701822f0(50)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x170280a00 H:[UIImageView:0x1701fab00(44)]>

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.
2014-10-25 18:28:14.280 Air Plan[1579:580797] 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:0x170281090 H:[UIImageView:0x1701fae00(44)]>",
    "<NSLayoutConstraint:0x170281310 H:|-(10)-[UIImageView:0x1701fae00]   (Names: '|':UIView:0x170182220 )>",
    "<NSLayoutConstraint:0x1702813b0 H:[UIImageView:0x1701fae00]-(10)-[UILabel:0x155e5d620'titleLbl']>",
    "<NSLayoutConstraint:0x170281400 H:[UILabel:0x155e5d620'titleLbl']-(10)-|   (Names: '|':UIView:0x170182220 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x17409fd60 h=--& v=--& H:[UIView:0x170182220(50)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x170281090 H:[UIImageView:0x1701fae00(44)]>

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.
2014-10-25 18:28:14.282 Air Plan[1579:580797] 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:0x170281b80 H:[UIImageView:0x1701fb100(44)]>",
    "<NSLayoutConstraint:0x17409f4a0 H:|-(10)-[UIImageView:0x1701fb100]   (Names: '|':UIView:0x170182150 )>",
    "<NSLayoutConstraint:0x17409f5e0 H:[UIImageView:0x1701fb100]-(10)-[UILabel:0x155d64210'detailLbl']>",
    "<NSLayoutConstraint:0x17409f680 H:[UILabel:0x155d64210'detailLbl']-(10)-|   (Names: '|':UIView:0x170182150 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x1742800f0 h=--& v=--& H:[UIView:0x170182150(50)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x170281b80 H:[UIImageView:0x1701fb100(44)]>

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.
like image 458
Josh Kahane Avatar asked Oct 25 '14 17:10

Josh Kahane


2 Answers

I faced that problem too and fixed it by adding this inside the UICollectionViewCell subclass:

SWIFT >= 4.2

override func awakeFromNib() {
    contentView.autoresizingMask = [UIView.AutoresizingMask.flexibleWidth, UIView.AutoresizingMask.flexibleHeight]
}

SWIFT 3

override func awakeFromNib() {
    contentView.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight]
}

OBJC

- (void)awakeFromNib{
    self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}

Xcode 6.1 iOS 8.0.2, 8.1

You could also check this answer: UICollectionView Cell + UiLabel with AutoLayout

like image 127
Alexander Polovinka Avatar answered Oct 01 '22 11:10

Alexander Polovinka


Right after creation cell and cell's content view are 50x50 (doesn't matter what size is set by collection layout).

Auto layout first time works after cell got correct size but content view is still 50x50. Probably it's iOS 8 issue. Other layout works with correct content view size. So finely you see a correct layout but log output is littered.

Just set in awakeFromNib any frame bigger then minimal cell size to content view for iOS 8.

In your case

|-(10px)-UIImageView(44px)-(10px)-UILabel-(10px)-|

minimal cell width is 74 - sum of all explicit constants.

- (void)awakeFromNib {
    [super awakeFromNib];
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.) {
        self.contentView.frame = CGRectMake(0, 0, 200, 100);
    }
}

Had the same issue but setting auoresizingMask did not work. And setting frame resolved the issue.

like image 27
user1765464 Avatar answered Oct 01 '22 10:10

user1765464