API yang benar untuk digunakan adalah UIView systemLayoutSizeFittingSize:
, melewati salah satu UILayoutFittingCompressedSize
atau UILayoutFittingExpandedSize
.
Untuk UIView
penggunaan autolayout yang normal, ini hanya akan berfungsi selama kendala Anda benar. Jika Anda ingin menggunakannya pada UITableViewCell
(untuk menentukan tinggi baris misalnya) maka Anda harus menyebutnya terhadap sel Anda contentView
dan ambil tingginya.
Pertimbangan lebih lanjut ada jika Anda memiliki satu atau lebih UILabel dalam pandangan Anda yang multiline. Untuk ini, sangat penting bahwa preferredMaxLayoutWidth
properti diatur dengan benar sehingga label memberikan yang benar intrinsicContentSize
, yang akan digunakan dalam systemLayoutSizeFittingSize's
perhitungan.
EDIT: dengan permintaan, menambahkan contoh perhitungan tinggi untuk sel tampilan tabel
Menggunakan autolayout untuk penghitungan tinggi sel tabel tidak super efisien tetapi tentu saja nyaman, terutama jika Anda memiliki sel yang memiliki tata letak yang kompleks.
Seperti yang saya katakan di atas, jika Anda menggunakan multiline, UILabel
sangat penting untuk menyinkronkan preferredMaxLayoutWidth
ke lebar label. Saya menggunakan UILabel
subkelas khusus untuk melakukan ini:
@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
Berikut ini adalah subclass UITableViewController yang dibuat yang memperlihatkan 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
Sel khusus sederhana:
#import "TSTableViewCell.h"
#import "TSLabel.h"
@implementation TSTableViewCell
{
IBOutlet TSLabel* _label;
}
- (void) setText: (NSString *) text
{
_label.text = text;
}
@end
Dan, inilah gambar kendala yang didefinisikan di Storyboard. Perhatikan bahwa tidak ada batasan tinggi / lebar pada label - itu disimpulkan dari label intrinsicContentSize
: