你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> 如何使用masonry設計復合型cell

如何使用masonry設計復合型cell

編輯:IOS開發基礎

1.jpg

前言

其實早在@sunnyxx同學發布UIView-FDCollapsibleConstraints的時候 我就說要寫一下怎麼用代碼來稍微麻煩的實現復用的問題 但是一直各種沒時間(主要是我的辦法太復雜 - -) 正好看到@葉孤城同學也說了一下他的解決辦法 所以我來說一下我是如何解決這個問題的

分析

我們以葉孤城同學的例子來簡單分析一下 假設view是這樣的(為了方便 將所有的間隙設定為20)

正常的布局是這樣的

blob.png

布局代碼如下:

@interface ComplexCell()
@property (nonatomic, strong) UIView *vB; //view blue    height:30
@property (nonatomic, strong) UIView *vY; //view yellow  height:30
@property (nonatomic, strong) UIView *vR; //view red     height:30
@property (nonatomic, strong) UIView *vG; //view green   height:100
@end
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    
    
    
    if ( self ) {
        
        CGFloat spacing = 20.0f;
        
        self.vB = [UIView new];
        [self.contentView addSubview:self.vB];
        [self.vB mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.top.equalTo(self.contentView).insets(UIEdgeInsetsMake(spacing,spacing,0,0));
            make.width.equalTo(@60);
            make.height.equalTo(@30).priorityLow();
            self.cB = make.height.equalTo(@0).priority(UILayoutPriorityRequired);
        }];
        self.vB.backgroundColor = [UIColor blueColor];
        
        
        self.vY = [UIView new];
        [self.contentView addSubview:self.vY];
        [self.vY mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(self.vB.mas_right).offset(spacing);
            make.right.top.equalTo(self.contentView).insets(UIEdgeInsetsMake(spacing,0,0,spacing));
            make.height.equalTo(@30).priorityLow();
            self.cY = make.height.equalTo(@0).priority(UILayoutPriorityRequired);
        }];
        self.vY.backgroundColor = [UIColor yellowColor];
        
        self.vR = [UIView new];
        [self.contentView addSubview:self.vR];
        [self.vR mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(self.vB.mas_bottom).offset(spacing);
            make.left.right.equalTo(self.contentView).insets(UIEdgeInsetsMake(0,spacing,0,spacing));
            make.height.equalTo(@30).priorityLow();
            self.cR = make.height.equalTo(@0).priority(UILayoutPriorityRequired);
        }];
        self.vR.backgroundColor = [UIColor redColor];
        
        self.vG = [UIView new];
        [self.contentView addSubview:self.vG];
        [self.vG mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(self.vR.mas_bottom).offset(spacing);
            make.left.right.equalTo(self.contentView).insets(UIEdgeInsetsMake(0,spacing,0,spacing));
            make.height.equalTo(@100).priorityLow();
            self.cG = make.height.equalTo(@0).priority(UILayoutPriorityRequired);
        }];
        self.vG.backgroundColor = [UIColor greenColor];
        
    }
    
    return self;
}

實際效果如圖

blob.png

看上去還不錯

在Masonry中 針對單條的MASLayoutConstraint可以進行activedeactive操作 那麼意味著可以動態的啟用或者禁用某條預置的約束 所以我們只要預先設置一條高優先級的高度為0(或者寬度為0)的約束 然後在適當的時候激活它不就行了? 先嘗試隱藏紅色的view 隱藏後如下

blob.png

啊~哦~ 結果不正確 隱藏是隱藏了 但是間隙沒有隱藏 導致縫變大了 這是因為我們僅僅隱藏了view 而沒有隱藏view之間的間隔 那麼應該如何處理這種情況呢?

主流的做法是將這個view的所有約束值全設置成0 然後恢復的時候再還原 這種方法需要記錄原值 但是在前言我說了 要用稍微麻煩的方法來解決這個問題 所以肯定不是這樣做啦

我采用的方法是group法 具體如下圖

blob.png

其實在第一行還有一個groupview如圖

blob.png

但是因為圖顯示出來不太好看(不會畫圖 T_T ) 所以我隱藏了 具體可以看代碼細節

每個(或者每組)可以隱藏的view 都對應有一個group view(group其實就是包含了view和spacing) 需要隱藏的時候 直接隱藏這個group 就可以達到既隱藏view又縮短間隙的目的

代碼較長 大家可以選擇跳過 - -!

@interface ComplexCell()
@property (nonatomic, strong) MASConstraint *cF; //constraint first row
@property (nonatomic, strong) MASConstraint *cB; //constraint blue
@property (nonatomic, strong) MASConstraint *cY; //constraint yellow
@property (nonatomic, strong) MASConstraint *cR; //constraint red
@property (nonatomic, strong) MASConstraint *cG; //constraint green
@property (nonatomic, strong) UIView *gF; //group first row
@property (nonatomic, strong) UIView *gB; //group blue
@property (nonatomic, strong) UIView *gY; //group yellow
@property (nonatomic, strong) UIView *gR; //group red
@property (nonatomic, strong) UIView *gG; //group green
@property (nonatomic, strong) UIView *vB; //view blue    height:30
@property (nonatomic, strong) UIView *vY; //view yellow  height:30
@property (nonatomic, strong) UIView *vR; //view red     height:30
@property (nonatomic, strong) UIView *vG; //view green   height:100
@end
@implementation ComplexCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    
    
    if ( self ) {
        
        CGFloat spacing = 20.0f;
        
        
        self.gF = [UIView new];
        [self.contentView addSubview:self.gF];
        [self.gF mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.top.right.equalTo(self.contentView);
            
            self.cF = make.height.equalTo(@0).priority(UILayoutPriorityRequired);
            [self.cF deactivate];
        }];
        self.gF.clipsToBounds = YES;
        
        self.gB = [UIView new];
        [self.gF addSubview:self.gB];
        [self.gB mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.top.bottom.equalTo(self.gF);
            
            self.cB = make.width.equalTo(@0).priority(UILayoutPriorityRequired);
            [self.cB deactivate];
        }];
        self.gB.clipsToBounds = YES;
        
        self.gY = [UIView new];
        [self.gF addSubview:self.gY];
        [self.gY mas_makeConstraints:^(MASConstraintMaker *make) {
            make.right.top.bottom.equalTo(self.gF);
            make.left.equalTo(self.gB.mas_right);
            
            self.cY = make.width.equalTo(@0).priority(UILayoutPriorityRequired);
            [self.cY deactivate];
        }];
        self.gY.clipsToBounds = YES;
        
        self.gR = [UIView new];
        [self.contentView addSubview:self.gR];
        [self.gR mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.right.equalTo(self.contentView);
            make.top.equalTo(self.gF.mas_bottom);
            
            self.cR = make.height.equalTo(@0).priority(UILayoutPriorityRequired);
            [self.cR deactivate];
        }];
        self.gR.clipsToBounds = YES;
        
        self.gG = [UIView new];
        [self.contentView addSubview:self.gG];
        [self.gG mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.right.equalTo(self.contentView);
            make.top.equalTo(self.gR.mas_bottom);
            
            self.cG = make.height.equalTo(@0).priority(UILayoutPriorityRequired);
            [self.cG deactivate];
        }];
        self.gG.clipsToBounds = YES;
        
        
        self.vB = [UIView new];
        [self.gB addSubview:self.vB];
        [self.vB mas_makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self.gB).insets(UIEdgeInsetsMake(spacing, spacing, 0, 0)).priorityLow();
            make.height.equalTo(@30);
            make.width.equalTo(@60);
        }];
        self.vB.backgroundColor = [UIColor blueColor];
        
        
        self.vY = [UIView new];
        [self.gY addSubview:self.vY];
        [self.vY mas_makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self.gY).insets(UIEdgeInsetsMake(spacing, spacing, 0, spacing)).priorityLow();
            make.height.equalTo(@30);
        }];
        self.vY.backgroundColor = [UIColor yellowColor];
        
        self.vR = [UIView new];
        [self.gR addSubview:self.vR];
        [self.vR mas_makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self.gR).insets(UIEdgeInsetsMake(spacing, spacing, 0, spacing)).priorityLow();
            make.height.equalTo(@30);
        }];
        self.vR.backgroundColor = [UIColor redColor];
        
        self.vG = [UIView new];
        [self.gG addSubview:self.vG];
        [self.vG mas_makeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self.gG).insets(UIEdgeInsetsMake(spacing, spacing, 0, spacing)).priorityLow();
            make.height.equalTo(@100);
        }];
        self.vG.backgroundColor = [UIColor greenColor];
        
    }
    
    return self;
}

然後 為每種不同的布局定義一個枚舉(為了舉例我隨便定義的 0和1代表這個view是否被顯示)

typedef NS_ENUM(NSUInteger, ComplexType) {
    ComplexType1111,
    ComplexType1110,
    ComplexType0111,
    ComplexType0011,
    ComplexType0010,
    ComplexType1101
};
@interface ComplexCell : UITableViewCell
@property (nonatomic, assign) ComplexType type;
@end
- (void)setType:(ComplexType)type {
    
    [self.cF deactivate];
    [self.cB deactivate];
    [self.cY deactivate];
    [self.cR deactivate];
    [self.cG deactivate];
    
    switch (type) {
        case ComplexType1111:
        {
            break;
        }
        case ComplexType0111:
        {
            [self.cB activate];
            break;
        }
        case ComplexType0011:
        {
            [self.cF activate];
            break;
        }
        case ComplexType1110:
        {
            [self.cG activate];
            break;
        }
        case ComplexType1101:
        {
            [self.cR activate];
            break;
        }
        case ComplexType0010:
        {
            [self.cF activate];
            [self.cG activate];
            break;
        }
            
        default:
            break;
    }
}

這樣 在tableview的datasource中我們只要這樣做就可以了

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 6;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [ComplexCell getHeightByType:indexPath.row%6];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    ComplexCell* cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    cell.type = indexPath.row%6;
    
    return cell;
}

看看效果 是不是很不錯

blob.png

blob.png

blob.png

blob.png

blob.png

blob.png

小結

文中的demo可以在這裡找到 要注意的地方是約束的priority的設置 另外 這種方式也支持不定長內容的Autolayout

可能很多人看了覺得我在瞎折騰 明明一個挺簡單實現的東西 被我一弄 弄得又長又臭 其實不然 像我這種方法雖然麻煩了點(文章開頭就指出了) 但是面對稍微復雜點的需求 卻是更得心應手(其實有點類似DIV+CSS的感覺有木有?)

使用group的方式 面對同時在橫向和縱向都有隱藏要求的時候 會方便很多

比如文中舉的例子 第一行有時會隱藏藍色的按鈕 有時整個一行都會不顯示 這樣的話 當我想隱藏按鈕時 只要激活按鈕的約束 想隱藏整行時 只要激活整行的那條約束就行了

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved