Я пытаюсь обернуть многострочную метку в виде таблицы статического содержимого, расширяя строку по мере необходимости в tableView:heightForRowAtIndexPath:
Будучи статической таблицей, я могу установить IBOutlets
; мой ярлык _instructionLabel
.
Немного упрощая (на самом деле в таблице несколько строк), это выглядит так:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *labelText = _instructionLabel.text;
CGFloat labelWidth = _instructionLabel.frame.size.width;
CGSize constrainToSize = (CGSize){.width = labelWidth, .height = MAXFLOAT};
CGSize textSize = [labelText sizeWithFont:_instructionLabel.font constrainedToSize:constrainToSize lineBreakMode: _instructionLabel.lineBreakMode];
return textSize.height + 10;
}
(Прежде чем мы продолжим: я знаю, что UILabel
, вероятно, не отрисовывается в полную ширину. Я планирую выяснить, как компенсировать это позже, но здесь это не моя проблема.)
Вот проблема: labelWidth
неправильно. Снимок экрана с этикеткой во время выполнения на симуляторе iPad iOS 6 (книжная ориентация) имеет ширину около 438 пикселей. Я получаю 638. (В iOS 7 я получаю 728.)
Чтобы исправить это, я добавил эти строки в viewWillAppear
:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear: animated];
[self.tableView setNeedsLayout];
[self.tableView layoutIfNeeded];
[self.tableView reloadData];
}
Это вызывает второй проход через установку таблицы. Теперь labelWidth
намного ближе: 482. Но это намного дальше, чем я ожидал.
Я также пытался вызвать лейбл sizeToFit
, но, похоже, он опирается на те же неверные данные.
Я убедился, что размер метки в конце концов установлен правильно, поместив это в viewWillAppear
:
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
CGRect frame = _instructionLabel.frame;
NSLog(@"%@", NSStringFromCGRect(frame));
// Output: {{20, 0}, {438, 30}}
});
Как я могу убедиться, что ширина метки задана правильно до последнего вызова табличного представления heightForRowAtIndexPath
и перед его отрисовкой?
heightForRowAtIndexPath:
, верно? Так что другой обратный вызов на самом деле не помогает, за исключением того, что я могу обнаружить, что что-то пошло не так, иdispatch_async
reloadData
. 18.10.2013