天天看點

UITableView根據表格内容進行高度自适應與使用Masonry實作根據内容進行寬度自适應和高度自适應

Masonry和SDAutoLayout不同:SDAutoLayout需要上下左右四個方向都顯示性的進行限制,雖然當高度和寬度自适應時,可以少一個高度限制,但是也應有對應布局處理設定。因為标簽是有頂部和底部空白間隙的,通常高度比字型大小大一些(當字型很大時的粗體差别很大),當設定的高度比标簽實際高度小時,标簽的頂部和底部被截取。當然它也有好處,就是嚴格按照布局高度實作ui.而Masonry并非上下左右四個方向都設定限制,一般2到3個不重複方向的限制就可以(沒有就采用預設值推導)。就是設定上下左右的限制,它實際的标簽也是按照标簽的實際顯示高度上下留白白,這樣就造成和UI有稍微一點高度的偏差。可見他們各有優缺點,一般場景可以混用,帶自适應高度的布局場景不能混用。

Masonry的自适應寬度和高度大緻可以分為三類情況。

第一種情況:控件根據内容進行寬度自适應(就是省略左或右方向的一個限制):

[self.describeTitleLabel mas_makeConstraints:^(MASConstraintMaker make) {
 make.left.mas_equalTo(COMMON_BIG_EDGE_DISTANCE);
 // make.width.mas_equalTo(FULL_WIDTH-COMMON_EDGE_DISTANCE2);
 make.top.mas_equalTo(68+height+8);
 make.height.mas_equalTo(16.0);
 }];      

當然若你的控件是先加載控件,後填入内容就需要在重置内容後對控件進行重新布局:

[self.describeTitleLabel mas_updateConstraints:^(MASConstraintMaker make) {
 make.left.mas_equalTo(COMMON_BIG_EDGE_DISTANCE);
 // make.width.mas_equalTo(FULL_WIDTH-COMMON_EDGE_DISTANCE2);
 make.top.mas_equalTo(68+height+8);
 make.height.mas_equalTo(16.0);
 }];      

注意:Masonry是延遲布局生效,不是你剛調用mas_makeConstraints或mas_updateConstraints對控件進行布局後立即填充内容,它的寬度就是剛布局時的寬度。但是若控件已經加載出來,等大約1秒後你再對它指派,那麼你不對它重新布局,那麼它顯示的就是最開始的寬度。高度自适應也是如此。

第二種情況:非表格控件根據内容進行高度自适應(就是省略上或下方向的一個限制):

[content mas_makeConstraints:^(MASConstraintMaker *make) {
 make.left.mas_equalTo(COMMON_BIG_EDGE_DISTANCE);
 make.right.mas_equalTo(-COMMON_BIG_EDGE_DISTANCE);
 make.top.mas_equalTo(68.0);
 }];      

第三種情況:表格控件根據内容進行高度自适應,不但要對控件進行最大預計寬度設定(contentLab.preferredMaxLayoutWidth = SCREEN_WIDTH - BaseSize(43);),還要對表格高度進行自适應(不能有height限制),對表格高度設定為高度自适應的值(UITableViewAutomaticDimension)。

表格加載代碼:

• (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;
 }      
  • 表格控件布局函數部分代碼:
•  #import “MessageTableViewCell.h”
@implementation MessageTableViewCell
• (void)awakeFromNib {
 [super awakeFromNib];
 // Initialization code
 }• (void)setSelected:(BOOL)selected animated:(BOOL)animated {
 [super setSelected:selected animated:animated];
// Configure the view for the selected state
 }• (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
 self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
 if (self) {
 [self initCell];
 self.selectionStyle = UITableViewCellSelectionStyleNone;
}
 return self;
 }• (void)initCell{
 UILabel* contentLab = [UILabel labelWithText:@“ttttttttttttttttttttttt” font:SystemFontOfSize(14) textColor:TextBlackColor];
 contentLab.preferredMaxLayoutWidth = SCREEN_WIDTH - BaseSize(43);
 contentLab.numberOfLines = 0;
 contentLab.textAlignment = 0;
 [self.contentView addSubview:contentLab];
 self.contentLab = contentLab;
[contentLab mas_makeConstraints:^(MASConstraintMaker *make) {
 make.top.mas_equalTo(BaseSize(12)).;
 make.left.mas_equalTo(BaseSize(17));
 make.right.mas_equalTo(BaseSize(-26));
 make.bottom.mas_equalTo(-BaseSize(23.5));
}];
 }• (void)setMsg:(MessageModel *)msg {
 _msg = msg;
 self.contentLab.text = msg.Title;
 }@end      

其中最核心的代碼是:

contentLab.preferredMaxLayoutWidth = SCREEN_WIDTH - BaseSize(43);
contentLab.preferredMaxLayoutWidth = SCREEN_WIDTH - BaseSize(43);
    [contentLab mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(BaseSize(12)).;
        make.left.mas_equalTo(BaseSize(17));
        make.right.mas_equalTo(BaseSize(-26));
        make.bottom.mas_equalTo(-BaseSize(23.5));
        
    }];      

注意:若你是立即對表格指派或指派後局部更新,需要更新布局使用下面的代碼:

- (void)setMsg:(MessageModel *)msg {
    _msg = msg;
    self.contentLab.text = msg.Title;
    [self.contentLab mas_updateConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(BaseSize(12)).;
        make.left.mas_equalTo(BaseSize(17));
        make.right.mas_equalTo(BaseSize(-26));
        make.bottom.mas_equalTo(-BaseSize(23.5));
    }];
}      
[self.productNameLabel setMaxNumberOfLinesToShow:2];