简体   繁体   中英

Updating UITableViewCell constraints causes exception

I'm using Xcode 5 with the iOS 7 SDK. I have a UITableViewCell defined as a prototype in my storyboard and I'm using autolayout for the subviews within the cell. When the cell is requested by cellForRowAtIndexPath , I populate the cell with its data:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ActivityTableViewCell *tableViewCell = [tableView dequeueReusableCellWithIdentifier:@"Activity"];
    Activity *activity = self.activities[(NSUInteger)indexPath.row];

    [tableViewCell configureWithActivity:activity];

    return tableViewCell;
}

This data can cause the height of one of the subviews to change. I am changing the subview's height by modifying its constraint, along with other constraint modifications:

@implementation ActivityTableViewCell

- (void)updateConstraints
{
    // Update constraints based on the activity
    self.activityDocumentsTableViewHeightLayoutConstraint.constant = ...;
    self.betweenActivityDocumentsTableViewAndNotesLabelLayoutConstraint.constant = ...;
    self.activityNotesTableViewHeightLayoutConstraint.constant = ...;
    self.betweenActivityNotesTableViewAndContentViewLayoutConstraint.constant = ...;

    [super updateConstraints];
}

- (void)configureWithActivity:(Activity *)activity
{
    // Populate subviews using the activity variable

    [self setNeedsUpdateConstraints];
}

@end

My ActivityTableViewCell class derives from another class that tells the content view to automatically size to fit its dynamically-sized subviews:

self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

My view controller pre-calculates the heights of all of these cells and stores them in an array. Those heights are supplied in heightForRowAtIndexPath .

All of this works perfectly, until I scroll the table view:

2014-01-17 10:41:47.435 ... 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:0x13c4a520 UnknownLabel:0x13c4a440.height == 26>",
    "<NSLayoutConstraint:0x13c4ad20 BorderedTableView:0xd46e000.height == 54>",
    "<NSLayoutConstraint:0x13c4b800 UnknownLabel:0x13c4b720.height == 26>",
    "<NSLayoutConstraint:0x13c4be40 BorderedTableView:0xd462600.height == 74>",
    "<NSLayoutConstraint:0x13c4cc60 BorderedTableView:0xd46e000.top == UnknownLabel:0x13c4a440.bottom + 8>",
    "<NSLayoutConstraint:0x13c4ccc0 BorderedTableView:0xd462600.top == UnknownLabel:0x13c4b720.bottom + 8>",
    "<NSLayoutConstraint:0x13c4cd20 UITableViewCellContentView:0x13c49de0.bottom == BorderedTableView:0xd462600.bottom + 8>",
    "<NSLayoutConstraint:0x13c4cd50 UnknownLabel:0x13c4a440.top == UITableViewCellContentView:0x13c49de0.top + 20>",
    "<NSLayoutConstraint:0x13c4cd80 UnknownLabel:0x13c4b720.top == BorderedTableView:0xd46e000.bottom + 55>",
    "<NSAutoresizingMaskLayoutConstraint:0xb2c1bf0 UITableViewCellContentView:0x13c49de0.height == UITableViewCellScrollView:0x13c4d000.height>",
    "<NSAutoresizingMaskLayoutConstraint:0xb2c2460 UITableViewCellScrollView:0x13c4d000.height == ActivityTableViewCell:0x13c49be0.height>",
    "<NSAutoresizingMaskLayoutConstraint:0x13935110 ActivityTableViewCell:0x13c49be0.height == 318>"
)

Note that the sum of all the vertical constants does not total 318, thus the exception. The 318 is coming from my pre-calculated height and is the correct height for this cell. However, the fourth constraint in that exception, "<NSLayoutConstraint:0x13c4be40 BorderedTableView:0xd462600.height == 74>" , is incorrect (it was correct the first time this cell was dequeued and configured). That's because iOS appears to be applying the row height before calling my cell's updateConstraints method, which itself updates that fourth constraint to its correct value.

I have tried numerous combinations of calling updateConstraints , setNeedsLayout , etc., all to no avail. I simply cannot figure out how to prevent iOS from updating the autoresizing mask before my constraints have been updated. The good news is that after updateConstraints is called--and it eventually is--the constraints seem to work; I see my cell correctly and the size of all the subviews appears correct. I just don't like seeing these exceptions in the console and I'd prefer to eliminate them if possible.

Really no clean solution that I've found, other than changing the priority to 999 on one of the vertical constraints. This will eliminate the error message itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM