API chính xác để sử dụng là UIView systemLayoutSizeFittingSize:
, vượt qua UILayoutFittingCompressedSize
hoặc UILayoutFittingExpandedSize
.
Đối với một người bình thường UIView
sử dụng tính năng tự động thanh toán, điều này sẽ chỉ hoạt động miễn là các ràng buộc của bạn là chính xác. Nếu bạn muốn sử dụng nó trên một UITableViewCell
(để xác định chiều cao hàng chẳng hạn) thì bạn nên gọi nó dựa vào ô của bạn contentView
và lấy chiều cao.
Cân nhắc thêm tồn tại nếu bạn có một hoặc nhiều UILabel theo quan điểm của bạn là đa dòng. Đối với những điều này, điều bắt buộc là thuộc preferredMaxLayoutWidth
tính phải được đặt chính xác sao cho nhãn cung cấp chính xác intrinsicContentSize
, sẽ được sử dụng trong systemLayoutSizeFittingSize's
tính toán.
EDIT: theo yêu cầu, thêm ví dụ về tính toán chiều cao cho ô xem bảng
Sử dụng tính năng tự động thanh toán để tính toán chiều cao của ô bảng không phải là siêu hiệu quả nhưng chắc chắn sẽ thuận tiện, đặc biệt nếu bạn có một ô có bố cục phức tạp.
Như tôi đã nói ở trên, nếu bạn đang sử dụng đa dòng UILabel
, bắt buộc phải đồng bộ hóa preferredMaxLayoutWidth
với chiều rộng nhãn. Tôi sử dụng một UILabel
lớp con tùy chỉnh để làm điều này:
@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
Đây là một lớp con UITableViewControll được trình bày thể hiện 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
Một ô tùy chỉnh đơn giản:
#import "TSTableViewCell.h"
#import "TSLabel.h"
@implementation TSTableViewCell
{
IBOutlet TSLabel* _label;
}
- (void) setText: (NSString *) text
{
_label.text = text;
}
@end
Và, đây là hình ảnh về các ràng buộc được xác định trong Bảng phân cảnh. Lưu ý rằng không có ràng buộc về chiều cao / chiều rộng trên nhãn - chúng bị suy ra từ nhãn intrinsicContentSize
: