今天看啥  ›  专栏  ›  李yao~鹏

对tableView的封装(OC)

李yao~鹏  · 掘金  ·  · 2019-08-25 01:43
阅读 31

对tableView的封装(OC)

PYTableMainView

由于开发中经常需要修改tableView的组(cell)的顺序,或者控制组(cell)的显示与隐藏,

尴尬的是判断顺序的逻辑每次都至少要在以下地方修改

/// 得到 cell、header、footer
- (nullable __kindof UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath;
- (nullable UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;
- (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;

/// cell、header、footer 计算高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;

/// cell 点击事件
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;

复制代码

代码及其冗余,而且不聚合。不好维护

于是封装了PYTableMainView

PYTableMainView位于PYKit库中的PYBaseView

你可以这样引入 pod PYBaseView

demo在这里

特点

  1. 高聚合代码。

  2. 抛弃了组的限制,用类型或者key来区分cellheaderfooter

  3. 懒加载形式自动缓存每个cellheaderfooterframe

    1. 如果你发现缓存的frame不准确:

      1. 没有调用PYTableMainViewreloadData。你可以调用- (void) reloadIndexPathFrameCatch强制刷新缓存。

      2. 设置了tableView的 预估行高属性或实现了相应的代理,请设置成0

        estimatedSectionHeaderHeight

        estimatedSectionFooterHeight

        estimatedRowHeight

  4. 动态注册 headercellfooter

思路

  1. 封装一个结构体SBaseTabelViewData
    1. 其中封装了headercellfooter的基本属性:高度、类型、区分的key(是否为IXB)
  2. 在所有的需要判断组的地方,创建SBaseTabelViewData,并且调用相应的自定义代理。
  3. 在所有的自定义代理实现方法中,都使用headercellfooter类型/identifire来进行处理。
struct SBaseTabelViewData {
    /// 扩展key
    NSString * key;
    NSInteger sectionCount;
    NSInteger rowCount;
    
    Class rowType;
    Class headerType;
    Class footerType;
    
    NSString *rowIdentifier;
    NSString *headerIdentifier;
    NSString *footerIdentifier;
    
    CGFloat rowHeight;
    CGFloat rowWidth;
    CGFloat headerHeight;
    CGFloat headerWidth;
    CGFloat footerHeight;
    CGFloat footerWidth;
    
    BOOL isXibCell;
    BOOL isXibFooter;
    BOOL isXibHeader;
    /// 如果 (isXibCell && length<= 0) 那么cellNibName = NSStringFromClass(rowType)
    NSString *cellNibName;
};
typedef struct SBaseTabelViewData  SBaseTabelViewData;
复制代码

你可以实现下面的方法,来创建一个对应IndexPathSBaseTabelViewData

- (SBaseTabelViewData) getTableViewData:(PYTableMainView *)baseTableView andCurrentSection:(NSInteger)section andCurrentRow:(NSInteger)row
复制代码

所有的关于组的判断都在这个方法中统一处理。

例子

- (SBaseTabelViewData) getTableViewData:(PYTableMainView *)baseTableView andCurrentSection:(NSInteger)section andCurrentRow:(NSInteger)row {
    
    SBaseTabelViewData data = SBaseTabelViewDataMakeDefault();
    data.sectionCount = 6;
    
    if (section == 0) {
        data.rowCount = self.data1.count;
        data.rowHeight = 60;
        data.rowType = BaseTableTestCell1.class;
        data.rowIdentifier = KBaseTableTestCell1;
    }
    
    if (section == 1) {
        data.rowCount = self.data2.count;
        data.rowHeight = 30;
        data.rowType = BaseTableTestCell2.class;
        data.rowIdentifier = KBaseTableTestCell2;
        data.headerHeight = 40;
        data.headerIdentifier = KBasetableTestHeserFooterView1;
        data.headerType = BasetableTestHeserFooterView1.class;
    }
    
    if (section == 2) {
        data.rowCount = self.data3.count;
        data.rowHeight = 112;
        data.rowType = BaseTableTestCell3.class;
        data.rowIdentifier = KBaseTableTestCell3;
        data.headerHeight = 50;
        data.headerIdentifier = KBasetableTestHeserFooterView2;
        data.headerType = BasetableTestHeserFooterView2.class;
        data.isXibCell = true;
        data.key = KBaseTableTestCell3_data3;///根据key区分是第二组数据
    }
    
    if (section == 3) {
        data.rowCount = self.data4.count;
        data.rowHeight = 120;
        data.rowType = BaseTableTestCell3.class;
        data.rowIdentifier = KBaseTableTestCell3;
        
        data.headerHeight = 60;
        data.headerIdentifier = KBasetableTestHeserFooterView2;
        data.headerType = BasetableTestHeserFooterView2.class;
        data.isXibCell = true;
        data.key = KBaseTableTestCell3_data4;///根据key区分是第三组数据
    }
    return data;
}

复制代码

cell数据的传递

- (void)baseTableView:(PYTableMainView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath andData:(SBaseTabelViewData)data{
    
    if ([BaseTableTestCell1.class isEqual: cell.class]) {
    }
    
    if ([BaseTableTestCell2.class isEqual: cell.class]) {
        BaseTableTestCell2 *cell2 = (BaseTableTestCell2 *)cell;
        cell2.titleLabel.text = self.data2[indexPath.row];
        cell2.subTitleLabel.text = self.data2[indexPath.row];
        __weak typeof(self)weakSelf = self;
        [cell2 setClickCallBack:^{
            [weakSelf.tableView reloadData];
        }];
    }
    
    if ([BaseTableTestCell3.class isEqual: cell.class]) {
        
        BaseTableTestCell3 *cell3 = (BaseTableTestCell3 *)cell;
        NSString *str = @"";
        
        if ([KBaseTableTestCell3_data3 isEqualToString:data.key]) {
            str = self.data3[indexPath.row];
        }
        
        if ([KBaseTableTestCell3_data4 isEqualToString:data.key]) {
            str = self.data4[indexPath.row];
        }
        
        NSArray <NSString *>*array = [str componentsSeparatedByString:@"<EB>"];
        cell3.nameLabel.text = array.firstObject;
        cell3.subTitleLabel.text = array.lastObject;
        cell3.delegate = self;
        [cell3 addGestureRecognizer: cell3.longPressGesture];
    }
}


- (void)tableView:(PYTableMainView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section andData: (SBaseTabelViewData)data {
    
    if ([BasetableTestHeserFooterView1.class isEqual:view.class]) {
        BasetableTestHeserFooterView1 *header = (BasetableTestHeserFooterView1 *)view;
        header.titleLabel.text = @"设置";
    }
    
    /// 第二种headerView
    if ([BasetableTestHeserFooterView2.class isEqual:view.class]) {
        BasetableTestHeserFooterView2 *header = (BasetableTestHeserFooterView2 *)view;
        
        /// 用key区分header的类型
        if ([data.key isEqualToString:KBaseTableTestCell3_data3]) {
            header.titleLabel.text = @"小的绿萝";
            header.rightPointView.backgroundColor = UIColor.redColor;
        }
        if ([data.key isEqualToString:KBaseTableTestCell3_data4]) {
            header.titleLabel.text = @"大的鹅鹅鹅掌柴";
            header.rightPointView.backgroundColor = UIColor.blueColor;
        }
    }
}
复制代码

PYTableMainView位于PYKit库中的PYBaseView

你可以这样引入 pod PYBaseView

demo在这里




原文地址:访问原文地址
快照地址: 访问文章快照