Ответ 1
Несколько наблюдений:
-
Ваше создание этого конкретного ограничения верное. Ясно, что вы не можете просто установить левое ограничение, но вам нужно указать все ограничения, которые однозначно определяют
frame
подзонов соты. Например, определите не только левое (или ведущее) ограничение, но также ограничения сверху, снизу и ширины. Или определите левое ограничение плюс ограничения ширины и высоты и укажите вертикальное ограничение y. Много разных способов сделать это, но ключ заключается в том, что вы должны добавить все ограничения, которые однозначно определяютframe
всех подзонов.Например, у вас может быть что-то вроде следующего:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; UIImageView *customImageView; UILabel *customLabel; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; customImageView = [[UIImageView alloc] init]; customImageView.translatesAutoresizingMaskIntoConstraints = NO; customImageView.tag = IMAGEVIEWTAG; [cell.contentView addSubview:customImageView]; [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customImageView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:25.0]]; [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customImageView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:30.0]]; [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customImageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeTop multiplier:1.0 constant:3.0]]; [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customImageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-3.0]]; customLabel = [[UILabel alloc] init]; customLabel.translatesAutoresizingMaskIntoConstraints = NO; customLabel.tag = LABELTAG; [cell.contentView addSubview:customLabel]; [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customLabel attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:customImageView attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:10.0]]; [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customLabel attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:-10.0]]; [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customLabel attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeTop multiplier:1.0 constant:3.0]]; [cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customLabel attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-3.0]]; } else { customImageView = (id)[cell.contentView viewWithTag:IMAGEVIEWTAG]; customLabel = (id)[cell.contentView viewWithTag:LABELTAG]; } customImageView.image = ...; customLabel.text = ...; return cell; }
Очевидно, что вы часто используете подкласс
UITableViewCell
, чтобы облегчить процесс отслеживания ваших пользовательских элементов управления, но я хотел бы упростить пример. -
Если вы никогда не знаете, были ли ограничения определены однозначно, запустите приложение и после того, как пользовательский интерфейс был представлен, приостановите приложение и введите следующее в приглашении
(lldb)
:po [[UIWindow keyWindow] _autolayoutTrace]
Это сообщит вам, если какое-либо из представлений неоднозначно определено (т.е. отсутствуют ли какие-либо ограничения).
Если вы хотите увидеть, что
frame
для всех представлений, вы можете ввести следующее в приглашении(lldb)
:po [[UIWindow keyWindow] recursiveDescription]
-
Обязательно укажите
translatesAutoresizingMaskIntoConstraints
-NO
для всех подзонов, как это было в приведенном выше примере кода. -
Пока вы можете определить ограничения с помощью
constraintWithItem
, часто люди будут использоватьconstraintsWithVisualFormat
, так как вы можете часто определять ограничения более кратко. Сравните этот пример кода с этим примером кода:- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; UIImageView *customImageView; UILabel *customLabel; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; customImageView = [[UIImageView alloc] init]; customImageView.translatesAutoresizingMaskIntoConstraints = NO; customImageView.tag = IMAGEVIEWTAG; [cell.contentView addSubview:customImageView]; customLabel = [[UILabel alloc] init]; customLabel.translatesAutoresizingMaskIntoConstraints = NO; customLabel.tag = LABELTAG; [cell.contentView addSubview:customLabel]; NSDictionary *views = NSDictionaryOfVariableBindings(customImageView, customLabel); [cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-25-[customImageView(30)]-[customLabel]|" options:0 metrics:nil views:views]]; [cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-3-[customImageView]-3-|" options:0 metrics:nil views:views]]; [cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-3-[customLabel]-3-|" options:0 metrics:nil views:views]]; } else { customImageView = (id)[cell.contentView viewWithTag:IMAGEVIEWTAG]; customLabel = (id)[cell.contentView viewWithTag:LABELTAG]; } customImageView.image = ...; customLabel.text = ...; return cell; }