Правильный API для использования - UIView systemLayoutSizeFittingSize:
, проходящий либо UILayoutFittingCompressedSize
, либо UILayoutFittingExpandedSize
.
Для нормального UIView
с использованием автозапуска это должно работать только при условии правильности ваших ограничений. Если вы хотите использовать его на UITableViewCell
(чтобы определить, например, высоту строки), вы должны вызвать его против своей ячейки contentView
и захватить высоту.
Дополнительные соображения существуют, если у вас есть один или несколько UILabel в вашем представлении, которые являются многострочными. Для них крайне важно правильно установить свойство preferredMaxLayoutWidth
таким образом, чтобы метка давала правильный intrinsicContentSize
, который будет использоваться в расчете systemLayoutSizeFittingSize's
.
EDIT: по запросу, добавив пример расчета высоты для табличного ячейки
Использование autolayout для расчета высоты таблицы ячейки не супер эффективным, но он уверен, это удобно, особенно если у вас есть клетки который имеет сложный макет.
Как я сказал выше, если вы используете многострочный UILabel
, необходимо синхронизировать preferredMaxLayoutWidth
с шириной метки. Я использую обычай UILabel
подкласса, чтобы сделать это:
@implementation TSLabel
- (void) layoutSubviews
{
[super layoutSubviews];
if (self.numberOfLines == 0)
{
if (self.preferredMaxLayoutWidth != self.frame.size.width)
{
self.preferredMaxLayoutWidth = self.frame.size.width;
[self setNeedsUpdateConstraints];
}
}
}
- (CGSize) intrinsicContentSize
{
CGSize s = [super intrinsicContentSize];
if (self.numberOfLines == 0)
{
// found out that sometimes intrinsicContentSize is 1pt too short!
s.height += 1;
}
return s;
}
@end
Вот надуманный UITableViewController подкласс демонстрирует heightForRowAtIndexPath:
#import "TSTableViewController.h"
#import "TSTableViewCell.h"
@implementation TSTableViewController
- (NSString*) cellText
{
return @"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
}
#pragma mark - Table view data source
- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView
{
return 1;
}
- (NSInteger) tableView: (UITableView *)tableView numberOfRowsInSection: (NSInteger) section
{
return 1;
}
- (CGFloat) tableView: (UITableView *) tableView heightForRowAtIndexPath: (NSIndexPath *) indexPath
{
static TSTableViewCell *sizingCell;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sizingCell = (TSTableViewCell*)[tableView dequeueReusableCellWithIdentifier: @"TSTableViewCell"];
});
// configure the cell
sizingCell.text = self.cellText;
// force layout
[sizingCell setNeedsLayout];
[sizingCell layoutIfNeeded];
// get the fitting size
CGSize s = [sizingCell.contentView systemLayoutSizeFittingSize: UILayoutFittingCompressedSize];
NSLog(@"fittingSize: %@", NSStringFromCGSize(s));
return s.height;
}
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath
{
TSTableViewCell *cell = (TSTableViewCell*)[tableView dequeueReusableCellWithIdentifier: @"TSTableViewCell" ];
cell.text = self.cellText;
return cell;
}
@end
Простые пользовательские ячейки:
#import "TSTableViewCell.h"
#import "TSLabel.h"
@implementation TSTableViewCell
{
IBOutlet TSLabel* _label;
}
- (void) setText: (NSString *) text
{
_label.text = text;
}
@end
И вот картина ограничения, определенные в раскадровке. Обратите внимание, что нет высота/ширина ограничения на этикетке - те выведенные из лейбла intrinsicContentSize
:
Вы должны выбрать один из приведенных ниже ответов, так как для уверен, Том Свифт ответил на ваш вопрос. Все плакаты потратили огромное количество времени, чтобы помочь вам, теперь вы должны сделать свою часть и выбрать ответ, который вам больше нравится. –