1. 程式人生 > >Masonry自動計算行高

Masonry自動計算行高

前言

還在手動計算UITableViewCell的行高嗎?還在每次都因為需求變化一點就要大量調整cell的高度而煩惱嗎?現在教大家如何通過Masonry的自動佈局來實現自動計算cell的行高!!!

github沒有找到基於Masonry自動計算行高的庫,倒是找到了使用xib/storyboard在新增約束來自動計算行高的庫,如: UITableView-FDTemplateLayoutCell

本人非常推崇Masonry來實現程式碼的自動佈局,因此專案中都是使用Masonry佈局的,為了自動計算行高,決定寫一個擴充套件,以達到自動計算的效果,如此一來,開發者不用再關心那些非固定行高的cell

的動態計算問題了。

設定關鍵依賴

要想自動計算出cell的行高,我們還需要指定以哪個檢視作為cell的最後一個檢視,比如我們最後要新增一條線,我們可以以這條線作為hyb_lastViewInCell,如果這條線還需要距離底部一定距離,那麼可以設定hyb_bottomOffsetToCell

/**
 * 必傳設定的屬性,也就是在cell中的contentView內最後一個檢視,用於計算行高
 * 例如,建立了一個按鈕button作為在cell中放到最後一個位置,則設定為:self.hyb_lastVieInCell = button;
 * 即可。
 * 預設為nil,如果在計算時,值為nil,會crash
 */
@property (nonatomic, strong) UIView *hyb_lastViewInCell; /** * 可選設定的屬性,預設為0,表示指定的hyb_lastViewInCell到cell的bottom的距離 * 預設為0.0 */ @property (nonatomic, assign) CGFloat hyb_bottomOffsetToCell;

計算行高API

要計算行高,只需要在UITableView的計算行高的代理方法中呼叫此API即可:

/**
 * 通過此方法來計算行高,需要在config中呼叫配置資料的API
 *
 * @param indexPath 必傳,對應的indexPath
 * @param
confi 必須要實現,且需要呼叫配置資料的API * * @return 計算的行高 */
+ (CGFloat)hyb_heightForIndexPath:(NSIndexPath *)indexPath config:(HYBCellBlock)config;

在呼叫時,config傳回來了cell物件,需要在呼叫處呼叫方法來配置好資料,才能正確地計算出cell的行高。通常是這樣呼叫的:

- (CGFloat)tableView:(nonnull UITableView *)tableView heightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
  HYBNewsModel *model = nil;
  if (indexPath.row < self.dataSource.count) {
    model = [self.dataSource objectAtIndex:indexPath.row];
  }

  return [HYBNewsCell hyb_heightForIndexPath:indexPath config:^(UITableViewCell *sourceCell) {
    HYBNewsCell *cell = (HYBNewsCell *)sourceCell;

    // 配置資料
    [cell configCellWithModel:model];
  }];
}

實現例子

效果圖如下:

image

我們看下實現-initWithStyle: reuseIdentifier:方法,因為我們要自動計算cell行高會自動呼叫此方法,因此一定要實現此方法來佈局:

- (nonnull instancetype)initWithStyle:(UITableViewCellStyle)style
                      reuseIdentifier:(nullable NSString *)reuseIdentifier {
  if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
    self.mainLabel = [[UILabel alloc] init];
    [self.contentView addSubview:self.mainLabel];
    self.mainLabel.numberOfLines = 0;
    [self.mainLabel sizeToFit];
    [self.mainLabel mas_makeConstraints:^(MASConstraintMaker *make) {
      make.left.mas_equalTo(15);
      make.top.mas_equalTo(20);
      make.right.mas_equalTo(-15);
      make.height.mas_lessThanOrEqualTo(80);
    }];
    // 如果需要支援6.0,需要加上這句
//    self.mainLabel.preferredMaxLayoutWidth = ...

    self.descLabel = [[UILabel alloc] init];
    [self.contentView addSubview:self.descLabel];
    self.descLabel.numberOfLines = 0;
    [self.descLabel sizeToFit];
    [self.descLabel mas_makeConstraints:^(MASConstraintMaker *make) {
      make.left.mas_equalTo(15);
      make.right.mas_equalTo(-15);
      make.top.mas_equalTo(self.mainLabel.mas_bottom).offset(15);
    }];
    // 如果需要支援6.0,需要加上這句
    //    self.mainLabel.preferredMaxLayoutWidth = ...

    self.button = [UIButton buttonWithType:UIButtonTypeSystem];
    [self.contentView addSubview:self.button];
    [self.button sizeToFit];
    [self.button setTitle:@"我是cell的最後一個" forState:UIControlStateNormal];
    [self.button setBackgroundColor:[UIColor greenColor]];
    [self.button mas_makeConstraints:^(MASConstraintMaker *make) {
      make.left.mas_equalTo(15);
      make.right.mas_equalTo(-15);
      make.height.mas_equalTo(45);
      make.top.mas_equalTo(self.descLabel.mas_bottom).offset(40);
    }];

    // 必須加上這句
    self.hyb_lastViewInCell = self.button;
    self.hyb_bottomOffsetToCell = 20;
  }

  return self;
}

注意到這兩行程式碼了嗎:

self.hyb_lastViewInCell = self.button;
self.hyb_bottomOffsetToCell = 20;

先是設定哪個檢視作為cell的最後一個檢視,然後設定了最後一個參考檢視與cell的底部的距離。其中,self.hyb_lastViewInCell屬性是必須要設定的,否則會丟擲異常。

使用

這個元件是開源的,而且是支援cocoapods的,因此大家若是使用了cocoapods來管理專案第三方庫,可以這樣使用:

pod 'HYBMasonryAutoCellHeight', '~> 0.0.1'

如果專案未使用cocoapods,直接下載原始碼,然後將HYBMasonryAutoCellHeight資料夾拖入工程即可使用!

原始碼

大家可以到github下載原始碼來看看,內部實現很簡單,當然要實現自動計算行高也是有系統方法的,不一定需要像筆者這樣來實現。

喜歡就給個star

關注我

如果在使用過程中遇到問題,或者想要與我交流,可加入有問必答

支援並捐助

如果您覺得文章對您很有幫助,希望得到您的支援。您的捐肋將會給予我最大的鼓勵,感謝您的支援!

支付寶捐助 微信捐助
image image