Die richtige API ist UIView systemLayoutSizeFittingSize:
, entweder UILayoutFittingCompressedSize
oder zu übergeben UILayoutFittingExpandedSize
.
Bei einer normalen UIView
Verwendung von Autolayout sollte dies nur funktionieren, solange Ihre Einschränkungen korrekt sind. Wenn Sie es für a verwenden möchten UITableViewCell
(um beispielsweise die Zeilenhöhe zu bestimmen), sollten Sie es gegen Ihre Zelle aufrufen contentView
und die Höhe ermitteln.
Weitere Überlegungen bestehen, wenn Sie ein oder mehrere UILabels in Ihrer Ansicht haben, die mehrzeilig sind. Für diese ist es unbedingt erforderlich, dass die preferredMaxLayoutWidth
Eigenschaft korrekt festgelegt wird, sodass die Beschriftung eine korrekte Eigenschaft enthält intrinsicContentSize
, die bei der systemLayoutSizeFittingSize's
Berechnung verwendet wird.
BEARBEITEN: Auf Anfrage wird ein Beispiel für die Höhenberechnung für eine Tabellenansichtszelle hinzugefügt
Die Verwendung von Autolayout für die Berechnung der Tabellenzellenhöhe ist nicht sehr effizient, aber sicher praktisch, insbesondere wenn Sie eine Zelle mit einem komplexen Layout haben.
Wie oben erwähnt, ist es bei Verwendung einer mehrzeiligen UILabel
Datei unbedingt erforderlich, die preferredMaxLayoutWidth
mit der Etikettenbreite zu synchronisieren . Ich benutze dazu eine benutzerdefinierte UILabel
Unterklasse:
@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
Hier ist eine erfundene UITableViewController-Unterklasse, die heightForRowAtIndexPath demonstriert:
#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
Eine einfache benutzerdefinierte Zelle:
#import "TSTableViewCell.h"
#import "TSLabel.h"
@implementation TSTableViewCell
{
IBOutlet TSLabel* _label;
}
- (void) setText: (NSString *) text
{
_label.text = text;
}
@end
Und hier ist ein Bild der im Storyboard definierten Einschränkungen. Beachten Sie, dass das Etikett keine Höhen- / Breitenbeschränkungen enthält. Diese werden aus den folgenden Angaben abgeleitet intrinsicContentSize
: