Подтвердить что ты не робот

AutoLayout прерывает ограничения при вызове layoutIfNeeded()

Я пытаюсь реализовать динамическую высоту UITaleViewCell в UITableView с помощью XCode6 с помощью Swift.

Я выложил свою ячейку следующим образом, установив ограничения графически (снимок экрана из XCode5, из-за NDA на XCode6). Я также установил свойство BodyLabel Line Break на "Word Wrap" и установил номер линии в "0", чтобы разрешить несколько строк.

enter image description here

Теперь, если я просто настроил содержимое ячейки внутри метода tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?), то я правильно вернусь к динамической высоте.

Однако, поскольку я следил за учебниками, доступными онлайн (в частности этот), я добавил еще один метод определения высоты ячейки с помощью tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!). В учебнике, который я читал, он сказал мне добавить cell.layoutIfNeeded(), поэтому я добавил это тоже.

override func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {

    var cell = tableView!.dequeueReusableCellWithIdentifier(kCellIdentifier) as GroupFeedCell

    // Configure the cell
    if let frc = self.fetchedResultsController {
        let feed = frc.objectAtIndexPath(indexPath) as GroupFeed
        cell.titleLabel.text = feed.name
        if let message = feed.message {
            cell.bodyLabel.text = message
        }
    }

    // Layout the cell
    cell.layoutIfNeeded()

    // Get the height
    var height : CGFloat = cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
    return height
}

Однако, когда я запускал программу, хотя представление таблицы по-прежнему отображало динамические высоты ячеек правильно, оно отображало такие ошибки:

2014-07-27 13:59:22.599 FBGroups[4631:979424] 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:0x17809e780 H:[UILabel:0x14fd12f50'Body Label Contents...']-(8)-|   (Names:    '|':UITableViewCellContentView:0x178185d70 )>",
    "<NSLayoutConstraint:0x17809e7d0 H:|-(8)-[UILabel:0x14fd12f50'Body Label Contents...']   (Names:    '|':UITableViewCellContentView:0x178185d70 )>",
    "<NSLayoutConstraint:0x17809ea50 'UIView-Encapsulated-Layout-Width' H:[UITableViewCellContentView:0x178185d70(0)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x17809e780 H:[UILabel:0x14fd12f50'Body Label Contents...']-(8)-|   (Names:     '|':UITableViewCellContentView:0x178185d70 )>

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.  

Я попытался выяснить, что могло пойти не так, и потратить на это много времени, и я понял, что всякий раз, когда я удаляю метод cell.layoutIfNeeded(), ошибка с ошибками исчезает.

И казалось, что среди противоречивых ограничений UIView-Encapsulated-Layout-Width не был тем, который я добавил, и, кроме этого, все ограничения выглядели невиновными для меня. Я попытался найти, что могло бы сгенерировать ограничения UIView-Encapsulated-Layout-Width, но я не смог получить удовлетворительное объяснение в моей ситуации. Я хотел бы знать, что послужило бы причиной этого сообщения об ошибке и как решить эту проблему.

Кроме того, может ли кто-нибудь объяснить, что было бы целью вызова метода cell.layoutIfNeeded() внутри вычисления высоты ячейки, и когда это было необходимо? Большинство обучающих программ, которые охватывали динамическую высоту UITableViewCell, использовали этот метод, хотя моя программа по-прежнему отображала ячейки правильно без вызова этого метода, и всякий раз, когда я пытался использовать этот метод, это вызывало исключения.

4b9b3361

Ответ 1

В Xcode установите приоритет самого нижнего вертикального ограничения на 750 (или что-нибудь меньшее, чем 1000).

Ответ 2

Может быть, конфликтующие ограничения связаны с тем, что первые два ограничения определяют ширину метки как 16pts меньше ширины ячейки, но третье ограничение UIView-Encapsulated-Layout-Width хочет сделать ярлык разным размером.

Вы можете попытаться снизить значения свойств сжатия/обжатия содержимого, чтобы позволить ярлыку игнорировать его собственный размер.

Ответ 3

Кажется, это ошибка Apple. Я использую работу, которая добавляет ограничение width во время выполнения, как это.

- (void)configurateBodyLabelConstraint {
    UIScreen *mainScreen = [UIScreen mainScreen];
    CGFloat viewWidth = mainScreen.bounds.size.width;
    CGFloat bodyLabelWidth = viewWidth - 76 - 8;
    NSDictionary *metric = @ {
        @"bodyLabelWidth": [NSNumber numberWithFloat:bodyLabelWidth]
    };

    UILabel *bodyLabel = self.bodyLabel;
    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"[bodyLabel(bodyLabelWidth)]"
                                                                   options:0
                                                                   metrics:metric
                                                                     views:@ {
                                                                         @"bodyLabel": bodyLabel
                                                                     }];
    [self.contentView addConstraints:constraints];
}

Ответ 4

cell.layoutIfNeeded() - не нужно вызывать. Создать IBOutlet NSLayoutConstraint