Позиция UILabel в UITableViewCell завершается с первой попытки
Как только мои ноги мокрые с развитием iOS, поэтому я надеюсь, что я получу правильный уровень детализации здесь...
У меня есть UILabel
, загруженный в ячейку таблицы, созданную с помощью .xib. На самом деле несколько ярлыков, одна из которых имеет разную длину (и, следовательно, меняет обернутую высоту). heightForRowAtIndexPath
и т.д. должным образом переопределены, а требуемая высота для обеих меток вычисляется правильно и назначается каждому .frame
Как только оба размера были установлены, я устанавливаю frame.origin.y меньшего (фиксированная длина, всегда одна строка с высокой) меткой, чтобы соответствовать ярлыку большей метки. Это работает, насколько можно видеть, переходя через cellForRowAtIndexPath
, но при первоначальном отображении вновь созданной ячейки начало координат в контейнере не является вертикально-центрированным, а не сверху.
После нажатия "через" ячейку на другое представление и возврата к контейнеру (теперь повторно используемому и предположительно уже подходящему размеру) позиция устанавливается как раньше, и она появляется там, где я ожидал.
Кажется, что размер контейнера изменяется после возврата cellForRowAtIndexPath
и что где-то там найдена новая позиция для нашего ярлыка; это объясняет, почему повторное использование ячейки позже устраняет проблему.
Я пробовал все, казалось бы, разумные комбинации внутренних и внешних настроек режима и базовой линии, настройки растяжения и т.д. Потеря для объяснений и/или обходных путей.
Update:
Предложение о Изменение позиции пользовательского UIButton в пользовательском UITableViewCell разрешило проблему. Решение заключалось в подклассе UITableViewCell
и переопределении layoutSubviews
, тем самым получив возможность повторно позиционировать подэлементы после того, как TableView выполнил свое нормальное позиционирование. Закроет это один раз, или тот человек ответит здесь, или истекает срок, и я отвечу сам, с кодом.
Ответы
Ответ 1
Если я делаю какой-либо сложный макет в UITableViewCell, я стараюсь не использовать его для cellForRowAtIndexPath. Один из вариантов - сделать макет в - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
, но я предпочитаю инкапсулировать макет в пользовательский класс UITableViewCell.
Создайте свой собственный подкласс UITableViewCell. Создайте и добавьте пользовательскую кнопку/метку/представление в элемент содержимого cellView в методе init, или создайте и добавьте его лениво через свойство accessor. Переопределите layoutSubviews и разместите кнопку по желанию.
Что-то вроде этого:
@implementation MyCustomCell
- (void) init
{
self = [super initWithStyle: UITableViewCellStyleDefault reuseIdentifier: nil];
if ( self != nil )
{
_myButton = [[UIButton buttonWithType: UIButtonTypeRoundedRect] retain];
[self.contentView addSubview: _myButton];
}
return self;
}
- (void) layoutSubviews
{
[super layoutSubviews];
// dynamic layout logic:
if ( ... )
{
_myButton.frame = CGRectMake( 10, 10, 100, 30 );
}
else
{
_myButton.frame = CGRectMake( 20, 10, 50, 30 );
}
}
Ответ 2
Я также столкнулся с подобной проблемой.
Размещение кода в этом методе работало для меня.
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
// here.
}