3 回答

TA貢獻(xiàn)1811條經(jīng)驗(yàn) 獲得超4個贊
正確使用的API UIView systemLayoutSizeFittingSize:是UILayoutFittingCompressedSize或傳遞UILayoutFittingExpandedSize。
對于正常UIView使用自動布局的方法,只要您的約束正確,它就應(yīng)該起作用。如果要在上使用它UITableViewCell(例如確定行高),則應(yīng)在單元格上調(diào)用它c(diǎn)ontentView并抓住它的高度。
如果您的視圖中有一個或多個多行UILabel,則需要進(jìn)一步考慮。對于這些,preferredMaxLayoutWidth必須正確設(shè)置屬性,以使標(biāo)簽提供正確的intrinsicContentSize,這將在systemLayoutSizeFittingSize's計算中使用。
編輯:根據(jù)要求,為表格視圖單元格添加高度計算的示例
使用自動布局進(jìn)行表格單元格高度計算雖然效率不是很高,但它確實(shí)很方便,特別是如果您的單元格具有復(fù)雜的布局。
如上所述,如果您使用多行,UILabel則必須將同步preferredMaxLayoutWidth到標(biāo)簽寬度。我使用自定義UILabel子類執(zhí)行此操作:
@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
這是一個人為設(shè)計的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
并且,這是情節(jié)提要中定義的約束的圖片。請注意,標(biāo)簽上沒有高度/寬度限制-從標(biāo)簽的推斷出這些限制intrinsicContentSize:

TA貢獻(xiàn)1834條經(jīng)驗(yàn) 獲得超8個贊
為了使視圖的大小由放置在其中的內(nèi)容確定,那么放置在其中的內(nèi)容必須與包含視圖具有顯式關(guān)系才能驅(qū)動其高度(或?qū)挾龋﹦討B(tài)?!疤砑幼右晥D”不會創(chuàng)建您可能假定的關(guān)系。您必須選擇哪個子視圖來驅(qū)動容器的高度和/或?qū)挾取畛R姷氖?,您在整個UI的右下角放置了任何UI元素。這是一些代碼和內(nèi)聯(lián)注釋來說明這一點(diǎn)。
請注意,這對于使用滾動視圖的用戶來說可能特別有價值,因?yàn)橥ǔ@一個內(nèi)容視圖進(jìn)行設(shè)計,該內(nèi)容視圖根據(jù)您放置的內(nèi)容動態(tài)確定其大小(并將其傳達(dá)給滾動視圖)。祝您好運(yùn),希望這對您有所幫助。
//
//? ViewController.m
//? AutoLayoutDynamicVerticalContainerHeight
//
#import "ViewController.h"
@interface ViewController ()
@property (strong, nonatomic) UIView *contentView;
@property (strong, nonatomic) UILabel *myLabel;
@property (strong, nonatomic) UILabel *myOtherLabel;
@end
@implementation ViewController
- (void)viewDidLoad
{
? ? // INVOKE SUPER
? ? [super viewDidLoad];
? ? // INIT ALL REQUIRED UI ELEMENTS
? ? self.contentView = [[UIView alloc] init];
? ? self.myLabel = [[UILabel alloc] init];
? ? self.myOtherLabel = [[UILabel alloc] init];
? ? NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_contentView, _myLabel, _myOtherLabel);
? ? // TURN AUTO LAYOUT ON FOR EACH ONE OF THEM
? ? self.contentView.translatesAutoresizingMaskIntoConstraints = NO;
? ? self.myLabel.translatesAutoresizingMaskIntoConstraints = NO;
? ? self.myOtherLabel.translatesAutoresizingMaskIntoConstraints = NO;
? ? // ESTABLISH VIEW HIERARCHY
? ? [self.view addSubview:self.contentView]; // View adds content view
? ? [self.contentView addSubview:self.myLabel]; // Content view adds my label (and all other UI... what's added here drives the container height (and width))
? ? [self.contentView addSubview:self.myOtherLabel];
? ? // LAYOUT
? ? // Layout CONTENT VIEW (Pinned to left, top. Note, it expects to get its vertical height (and horizontal width) dynamically based on whatever is placed within).
? ? // Note, if you don't want horizontal width to be driven by content, just pin left AND right to superview.
? ? [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_contentView]" options:0 metrics:0 views:viewsDictionary]]; // Only pinned to left, no horizontal width yet
? ? [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_contentView]" options:0 metrics:0 views:viewsDictionary]]; // Only pinned to top, no vertical height yet
? ? /* WHATEVER WE ADD NEXT NEEDS TO EXPLICITLY "PUSH OUT ON" THE CONTAINING CONTENT VIEW SO THAT OUR CONTENT DYNAMICALLY DETERMINES THE SIZE OF THE CONTAINING VIEW */
? ? // ^To me this is what's weird... but okay once you understand...
? ? // Layout MY LABEL (Anchor to upper left with default margin, width and height are dynamic based on text, font, etc (i.e. UILabel has an intrinsicContentSize))
? ? [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_myLabel]" options:0 metrics:0 views:viewsDictionary]];
? ? [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[_myLabel]" options:0 metrics:0 views:viewsDictionary]];
? ? // Layout MY OTHER LABEL (Anchored by vertical space to the sibling label that comes before it)
? ? // Note, this is the view that we are choosing to use to drive the height (and width) of our container...
? ? // The LAST "|" character is KEY, it's what drives the WIDTH of contentView (red color)
? ? [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[_myOtherLabel]-|" options:0 metrics:0 views:viewsDictionary]];
? ? // Again, the LAST "|" character is KEY, it's what drives the HEIGHT of contentView (red color)
? ? [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_myLabel]-[_myOtherLabel]-|" options:0 metrics:0 views:viewsDictionary]];
? ? // COLOR VIEWS
? ? self.view.backgroundColor = [UIColor purpleColor];
? ? self.contentView.backgroundColor = [UIColor redColor];
? ? self.myLabel.backgroundColor = [UIColor orangeColor];
? ? self.myOtherLabel.backgroundColor = [UIColor greenColor];
? ? // CONFIGURE VIEWS
? ? // Configure MY LABEL
? ? self.myLabel.text = @"HELLO WORLD\nLine 2\nLine 3, yo";
? ? self.myLabel.numberOfLines = 0; // Let it flow
? ? // Configure MY OTHER LABEL
? ? self.myOtherLabel.text = @"My OTHER label... This\nis the UI element I'm\narbitrarily choosing\nto drive the width and height\nof the container (the red view)";
? ? self.myOtherLabel.numberOfLines = 0;
? ? self.myOtherLabel.font = [UIFont systemFontOfSize:21];
}
@end

TA貢獻(xiàn)1793條經(jīng)驗(yàn) 獲得超6個贊
您可以通過創(chuàng)建約束并通過接口構(gòu)建器將其連接來完成此操作
參見說明:Auto_Layout_Constraints_in_Interface_Builder
raywenderlich開始自動布局
AutolayoutPG文章約束基礎(chǔ)
@interface ViewController : UIViewController {
IBOutlet NSLayoutConstraint *leadingSpaceConstraint;
IBOutlet NSLayoutConstraint *topSpaceConstraint;
}
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *leadingSpaceConstraint;
將此約束插座與您的子視圖約束連接,或者也可以將超級視圖約束連接,并根據(jù)您的要求進(jìn)行設(shè)置,例如:
self.leadingSpaceConstraint.constant = 10.0;//whatever you want to assign
我希望這可以澄清它。
- 3 回答
- 0 關(guān)注
- 628 瀏覽
添加回答
舉報