2013-06-30 7 views
0

У меня есть UITableViewController, сгруппированный стиль, с пользовательским UITableViewCell. В UITableViewCell у меня есть NSLayoutConstraints, определенные в раскадровке (в ячейке прототипа), которые определяют размер и расположение UIImageView. Эти NSLayoutConstraints связаны со свойствами подкласса UITableViewCell.Настройка NSLayoutConstraint на ячейку на UITableView

В - (пустотах) layoutSubviews способе наследнике UITableViewCell, я пытаюсь использовать

self.topSpacingConstraint.constant = 0; 

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

Эта строка кода регулирует ограничение для всех моих ячеек. Я не понимаю, почему, и я не знаю, как установить ограничение для одной ячейки.

Update

Вот полный код -(void)layoutSubviews метода подкласса UITableViewCell. self.topCell и self.bottomCell - это свойства, установленные UITableViewController при настройке ячейки. Исходя из этих значений, я пытаюсь обновить интервал AutoLayout изображения на основе каждой клетки:

- (void)layoutSubviews 
{ 
    [super layoutSubviews]; 

    UIImage *mask; 

    if (self.topCell && self.bottomCell) { 
     self.imageSpacingTopConstraint.constant = 1; 
     self.imageSpacingBottomConstraint.constant = 2; 
     mask = MTDContextCreateRoundedMask(self.wineImage.bounds, 6.0, 0.0, 6.0, 0.0); 
    } else if (self.topCell) { 
     self.imageSpacingTopConstraint.constant = 1; 
     self.imageSpacingBottomConstraint.constant = 0; 
     mask = MTDContextCreateRoundedMask(self.wineImage.bounds, 6.0, 0.0, 0.0, 0.0); 
    } else if (self.bottomCell) { 
     self.imageSpacingTopConstraint.constant = 0; 
     self.imageSpacingBottomConstraint.constant = 2; 
     mask = MTDContextCreateRoundedMask(self.wineImage.bounds, 0.0, 0.0, 6.0, 0.0); 
    } else { 
     self.imageSpacingTopConstraint.constant = 0; 
     self.imageSpacingBottomConstraint.constant = 0; 
     mask = MTDContextCreateRoundedMask(self.wineImage.bounds, 0.0, 0.0, 0.0, 0.0); 
    } 

    CALayer *layerMask = [CALayer layer]; 
    layerMask.frame = self.wineImage.bounds; 
    layerMask.contents = (id)mask.CGImage; 
    self.wineImage.layer.mask = layerMask; 
} 

Моей потребность сделать это вытекает из противоречивой высоты ячеек на столе с сгруппированным стилем. Верхняя и нижняя ячейки на 1pt выше, чем «средние» ячейки, в то время как одна ячейка в таблице на 2 метра выше. Использование одинаковых ограничений расстояния для изображения во всех ячейках приводит к тому, что изображение частично скрывает границы ячеек для некоторых ячеек или оставляет пробелы между изображением и границей в других.

Если кто-нибудь может подумать о более легком способе напасть на это, я был бы признателен.

Решение

Per маркированного решения ниже, устранение ограничений распорных изображений, а затем создать новые ограничения между изображением и cell.contentView сделал трюк. Я удалил код, чтобы скорректировать ограничения из метода -(void)layoutSubviews. Я добавил код, чтобы удалить и сделать новые ограничения для awakeFromNib подкласса UITableViewCell:

- (void)awakeFromNib 
{ 
    [super awakeFromNib]; 

    // Since Xcode 4.6.3 creates constrain relationships between the image and the cell, we need to delete and then recreate between the image and the cell.contentView 

    [self removeConstraint:self.imageSpacingTopConstraint]; 
    [self removeConstraint:self.imageSpacingBottomConstraint]; 

    self.imageSpacingTopConstraint = [NSLayoutConstraint constraintWithItem:self.wineImage attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]; 
    self.imageSpacingBottomConstraint = [NSLayoutConstraint constraintWithItem:self.wineImage attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]; 

    [self addConstraint:self.imageSpacingTopConstraint]; 
    [self addConstraint:self.imageSpacingBottomConstraint]; 
} 
+0

Разве ваши ячейки не используются повторно? Вам нужно будет сбросить это свойство в, например, 'cellForRowAtIndexPath'. –

+0

Они используются повторно, но я уверен, что это не проблема. Если я загружаю таблицу только тремя ячейками, все видимые и только изменяют значение прототипа для одного из трех, изменения макета во всех трех ячейках. –

+0

Пожалуйста, покажите полный метод layoutSubviews. – jrturton

ответ

2

Одна проблема вы обновляете свои ограничения в layoutSubviews, но layoutSubviews работает после Автокомпоновка. Вместо этого вы должны обновить свои ограничения в updateConstraints.

Другая проблема заключается в том, что Xcode, по крайней мере, версии 4.6.3, является ошибкой. Представление вашего изображения представляет собой подкласс ячейки contentView, а ограничения должны быть между изображением и contentView. Но в nibs и раскадровки Xcode неправильно устанавливает ограничения между представлением изображения и ячейкой. (Примечание: эта проблема была исправлена ​​в Xcode 5, поэтому вам, вероятно, не нужно беспокоиться об этом, если вы читаете это, если вы не путешествуете во времени.)

Если вы сориентируете свою иерархию в отладчике, вы обнаружите, что ячейки имеют разную высоту, но их содержимое имеет все одинаковые высоты. Вот размеры по умолчанию:

Section Size Row Position Cell Height contentView Height 

    1   sole   46    43 

    2   first   45    43 
    2   second   45    43 

    3+   first   45    43 
    3+   middle   44    43 
    3+   last   45    43 

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

Самым простым решением является просто написать код (в вашей ячейки awakeFromNib), которая удаляет ограничения с кончика пера/раскадровки, а также создает новые ограничения между contentView и вид изображения (и любых других подвидов в contentView.) Это следует исключить необходимость изменения констант ограничения на основе позиции ячейки в ее разделе.

+0

Выполнение того, что вы описали в своем последнем абзаце (удаление и повторное создание ограничений для 'contentView' позаботилось о проблеме для меня. Я отправлю код в своем' awakeFromNib' в исходном сообщении для всех, кто запускает в этот вопрос. Большое спасибо! –

0

Там не условность в вашем коде. Поэтому все ячейки меняются.

Теперь, когда вы добавили код, есть 2 причины, которые приходят на ум:

  1. если заявление не будет производить 0 константу, если topCell не nil. Это не совсем логично.

  2. Раздел слоя ниже оператора if может потенциально изменить ожидаемый макет снова.

+0

Я добавил полный код для '- (void) layoutSubviews', чтобы вы могли видеть условность. Извините, что я не включил это раньше. –

Смежные вопросы