4

For my project, I need to show a doctors list with a lot of information, for this I create a custom cell programmatically. Here is how my cell's view is structured :

Cell.contentView
  | --> UIView
    | --> UILabel (Title)
    | --> UILabel (Subtitle)
    | --> UIView (a simple separator, with a 1px height constraint)
    | --> UILabel (Address, multilines)

This is a simplified structure of what I really have, but it's enough to bring the warning.

And this is the 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:0x14f9a790 V:|-(11)-[UILabel:0x16058ea0'DR.NAME']   (Names: '|':DoctorHealthInformationView:0x16058f70 )>",
    "<NSLayoutConstraint:0x14f86300 V:[UILabel:0x16058ea0'DR.NAME']-(1.5)-[UILabel:0x160670e0'Chirurgien Dentiste']>",
    "<NSLayoutConstraint:0x14f86390 V:[UILabel:0x160670e0'Specialty']-(9)-[UIView:0x14e0fde0]>",
    "<NSLayoutConstraint:0x14f9ab20 V:[UIView:0x14e0fde0]-(8)-[KDCellLabel:0x14f90d10'Address\naddres...']>",
    "<NSLayoutConstraint:0x14f9ab50 KDCellLabel:0x14f90d10'Address\naddres...'.bottom == DoctorHealthInformationView:0x16058f70.bottom - 10>",
    "<NSLayoutConstraint:0x14f97a80 V:|-(0)-[DoctorHealthInformationView:0x16058f70]   (Names: '|':CustomDoctorCell:0x1605a890'OnlineCustomDoctorCell' )>",
    "<NSLayoutConstraint:0x14f88840 V:[DoctorHealthInformationView:0x16058f70]-(0)-[UIView:0x14f930d0]>",
    "<NSLayoutConstraint:0x14f889b0 V:[UIView:0x14f930d0(1)]>",
    "<NSLayoutConstraint:0x14f9ae10 UIView:0x14f9d330.bottom == CustomDoctorCell:0x1605a890'OnlineCustomDoctorCell'.bottom>",
    "<NSLayoutConstraint:0x14f9b120 V:[UIView:0x14f9d330(4)]>",
    "<NSLayoutConstraint:0x14f9af40 V:[UIView:0x14f930d0]-(0)-[UIView:0x14f9d330]>",
    "<NSLayoutConstraint:0x14f93020 'UIView-Encapsulated-Layout-Height' V:[CustomDoctorCell:0x1605a890'OnlineCustomDoctorCell'(44)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x14f86390 V:[UILabel:0x160670e0'Specialty']-(9)-[UIView:0x14e0fde0]>

My constraints :

The only height constraint I have is on my separator view, labels are pinned to superview by all the sides to allow my cell's height to be calculating by autolayout. If I remove my separator view and pin the top of the address label directly to the bottom of the subtitle label, the warning disappears. If I add a height constraint on one label, the warning comes back.

Some classic but maybe interesting methods :

For getting the height of a specified row :

TableViewController :

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    Doctor *doctor = (Doctor *)[_doctorsToShow objectAtIndex:indexPath.row];
    static CustomDoctorCell *sizingCellClassic = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sizingCellClassic = [[CustomDoctorCell alloc] initWithStyle:UITableViewCellStyleDefault
                                                    reuseIdentifier:classicDoctorCellIdentifier
                                                          forDoctor:doctor
                                                      showSpecialty:YES
                                               withAppointmentStyle:YES];
    });

    [sizingCellClassic updateContentForDoctor:doctor];
    return [CustomDoctorCell getCellHeightForCell:sizingCellClassic];
}

CustomDoctorCell :

+ (float) getCellHeightForCell:(CustomDoctorCell *)doctorCell
{
    [doctorCell setNeedsLayout];
    [doctorCell layoutIfNeeded];

    CGSize size = [doctorCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    return size.height;
}

I don't understand what I'm doing wrong, and what I have to do to remove this warning, I've tried to download this example form raywenderlich.com and simply add a height constraint on a label, I've got the same kind of warning.

One more thing, I have to be fully compatible with ios 7, that's why i'm not using the new features introduced by the sdk 8.

R.Lambert
  • 1,160
  • 1
  • 11
  • 25

2 Answers2

4

I ran into a similar situation when using a prototype cell in a storyboard; the UIView-Encapsulated-Layout-Height of the contentView mucked everything up. My solution was to do two things:

First, I set the priority of one of my vertical constraints to 999.

Second, I Set a "custom" row height for the Table View Cell in IB.

Custom Row Height

In my case, it's set to 266, but I don't think it really matters, as long as you have the "Custom" checkbox checked and it doesn't say "Default" in the Row Height input.

I initially worried that the lower priority vertical spacer constraint would mean that the manually entered custom height would take precedence, but it didn't. The table cell obeyed the constraints that I gave it.

It seems counterintuitive, but my hunch is that there's some pre-calculation going on which causes the conflict between the custom height and the vertical constraints inside the contentView, but at a layer point, maybe in layoutSubviews, the constraints take precedence and the app goes merrily about its business. So, I think the app takes a look at everything, attempts to break a constraint to appease rowHeight or estimatedRowHeight, then circles back and does what it was supposed to do in the first place. This is a complete guess, though. Regardless, it worked for my situation.

You mentioned that you were targeting iOS7, so I'm not sure that it will work for you, as I've only tested in iOS8, but our circumstances were so similar, this could be worth a shot. Given that it's iOS8, I'm using the new funcionality.

    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.tableView.estimatedRowHeight = (UIApplication.sharedApplication().keyWindow?.bounds.height)! * (460.0/1334.0)
John Nesbitt
  • 8,984
  • 1
  • 14
  • 7
  • Setting one height constraint priority to lower than 1000 works for me in iOS9. I still cannot understand why, I checked many times the Auto Layout constraints and they should not have problems. UITableViewCell's Auto Layout have been my headache for so many times... – Desmond DAI Oct 28 '16 at 03:36
1

The initial height of the cell is likely smaller than the vertical constraints. This creates an initial height conflict until the contentView's frame changes.

You can work around this issue using one of the following approaches:

  • Increase the cell's height in the storyboard to initially fit the content.

  • Change the bounds of the cell's contentView to a larger size:

    self.contentView.bounds = CGRectMake(0, 0, 99999, 99999);

You'll find more details in the answers to this auto layout question.

Community
  • 1
  • 1