cell自適應(yīng)高度,讓cell更自由


第一步:創(chuàng)建帶xib的單元格,并且在xib中添加約束

<p>
LayoutCell.h

#import <UIKit/UIKit.h>
@interface LayoutCell : UITableViewCell

@property (weak, nonatomic) IBOutlet UIView *a;
@property (weak, nonatomic) IBOutlet UIView *b;
@property (weak, nonatomic) IBOutlet UIView *c;
@property (weak, nonatomic) IBOutlet UIView *d;

@property (assign, nonatomic) NSInteger type;

@end

LayoutCell.m

#import "LayoutCell.h"

@interface LayoutCell()

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bH;// 視圖b的高
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *cH;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *dH;


@end

@implementation LayoutCell

- (void)setType:(NSInteger)type {
    switch (type) {
        case 0:
        {
            [self updateHeight:20 c:0 d:0];
        }
            break;
        case 1:
        {
            [self updateHeight:20 c:40 d:0];
        }
            break;
        case 2:
        {
            [self updateHeight:20 c:40 d:60];
        }
            break;
            
        default:
            break;
    }
    [UIView animateWithDuration:0.2 animations:^{
        [self.contentView layoutIfNeeded];
    }];
}

- (void)updateHeight:(CGFloat)b c:(CGFloat)c d:(CGFloat)d {
    self.bH.constant = b;
    self.cH.constant = c;
    self.dH.constant = d;
}

@end

LayoutCell.xib

<p>
b、c的約束就不贅述了,都是兩邊距離邊框0,上下距離上下視圖各為0,最后高度定值。

視圖a的約束 約束Top Space 決定單元格的上邊界

視圖d的約束 約束Bottom Space 決定單元格的下邊界,注意Bottom Space的邊界是虛線的, 那是因為這個約束的優(yōu)先等級為750,默認是1000 之所以降低優(yōu)先級,那是因為內(nèi)容視圖a、b、c、d之間互相有約束,在單元格高度不確定的情況下內(nèi)容視圖高度必須能夠根據(jù)內(nèi)容確定高度,這樣才能去決定單元格的高度,降低Bottom Space的優(yōu)先級就意味著先考慮其他約束,即等內(nèi)容視圖的約束互相影響確定了自身高度之后,之后,之后(三遍?。?,再根據(jù)Bottom Space調(diào)整單元格高度。 如果不降低Bottom Space的優(yōu)先級,xib會報錯,提示沒有指定子視圖的Y或者高度

注:單元格高度自適應(yīng)只要通過子視圖確定單元格的高度就可以了,寬度還是保持由子視圖去適應(yīng)單元格寬度。
注:autoLayout 出來之后,取代了原先的自適應(yīng)機制autoresizingMask,在UIView中有一個屬性translatesAutoresizingMaskIntoConstraints就是用來指定使用autoLayout還是autoresizingMask的,如果用了xib來創(chuàng)建視圖和約束,translatesAutoresizingMaskIntoConstraints會被自動修改為NO,即啟用autoLayout機制,這個時候約束才有用,根據(jù)約束來自適應(yīng)單元格高度才有效。

@property(nonatomic) BOOL translatesAutoresizingMaskIntoConstraints NS_AVAILABLE_IOS(6_0); // Default YES

</br>

完成第一步后,我們有兩種方式可以實現(xiàn)單元格自適應(yīng),區(qū)別在于api的出現(xiàn)時間,一種iOS8之后才可用,一種iOS6就可以用了。

<b>

</br>
從 iOS6 版本開始適配的方法:
<b>

第二步[iOS6]:聲明單元格變量,保持當(dāng)前單元格
@property(nonatomic,strong) UITableViewCell* prototypeCell;
self.prototypeCell  = [self.table dequeueReusableCellWithIdentifier:identifier];

<b>

第三步[iOS6]:在table計算高度的方法中實現(xiàn)高度自適應(yīng)
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    LayoutCell *cell = (LayoutCell *)self.prototypeCell;
    // 如果是手動添加的約束,必須將單元格中所有子視圖的translatesAutoresizingMaskIntoConstraints設(shè)為NO,即指定使用約束自適應(yīng)
    // 例:cell.translatesAutoresizingMaskIntoConstraints = NO;
    //     cell.a.translatesAutoresizingMaskIntoConstraints = NO;
    //     cell.b.translatesAutoresizingMaskIntoConstraints = NO;
    //     cell.c.translatesAutoresizingMaskIntoConstraints = NO;
    
    // 必須為cell賦值,即完成cellForRow中的任務(wù),因為調(diào)用tableView: heightForRowAtIndexPath:方法時 tableView: cellForRowAtIndexPath方法還沒有調(diào)用,這個時候刷新高度獲取的只是賦值之前的高度,不能實現(xiàn)高度自適應(yīng)的效果
    cell.type = [self.array[indexPath.row] integerValue];
    
    // 計算高度
    CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingExpandedSize];
    NSLog(@"h=%f", size.height + 1);
    return 1  + size.height;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 3;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    LayoutCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    cell.type = [self.array[indexPath.row] integerValue];
    
    return cell;
}

<b>

第四步[iOS6]:使用單元格高度自適應(yīng)功能

<b>

修改單元格的type屬性,單元格內(nèi)的子視圖約束將變更,這時候便能看到單元格高度自適應(yīng)的效果了

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView beginUpdates];
    self.array[indexPath.row] = [NSString stringWithFormat:@"%d",arc4random()%3];
    [tableView reloadData];
    [tableView endUpdates];
}

</br>
</br>
從 iOS8 版本開始適配的方法:
<b>

第二步[iOS8]:配置table,實現(xiàn)單元格自動計算高度功能
    // 二者缺一不可,需要注意的是不能再實現(xiàn)tableView: heightForRowAtIndexPath:方法了,該方法的優(yōu)先級更高,會覆蓋掉rowHeight。
    self.table.estimatedRowHeight = 60;
    self.table.rowHeight = UITableViewAutomaticDimension;

    [self.table registerNib:[UINib nibWithNibName:identifier bundle:nil] forCellReuseIdentifier:identifier];

<b>

第三步[iOS8]:使用單元格高度自適應(yīng)功能
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 3;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    LayoutCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    cell.type = [self.array[indexPath.row] integerValue];
    
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView beginUpdates];
    self.array[indexPath.row] = [NSString stringWithFormat:@"%d",arc4random()%3];
    [tableView reloadData];
    [tableView endUpdates];
}

<p>
效果圖:


layoutcell.gif
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,269評論 4 61
  • 轉(zhuǎn)載自:https://github.com/Tim9Liu9/TimLiu-iOS 目錄 UI下拉刷新模糊效果A...
    袁俊亮技術(shù)博客閱讀 12,146評論 9 105
  • 嗯哼嗯哼蹦擦擦~~~ 轉(zhuǎn)載自:https://github.com/Tim9Liu9/TimLiu-iOS 目錄 ...
    philiha閱讀 5,258評論 0 6
  • 溫暖的小毯子 海斯特 圖吉爾巴頓 鴨寶寶去哪都會帶著它的小毯子。有時它會被弄臟。今天是非常的臟。 鴨媽媽說“:到了...
    穆建園閱讀 956評論 0 2
  • 今日完成:AWU排版了一篇文章并發(fā)布。 今日心得:有一天晚上,我身體不太舒服,當(dāng)時我突然閃出一個念頭,萬一我死了,...
    楊小溪居士閱讀 587評論 1 0

友情鏈接更多精彩內(nèi)容