美文网首页iOS 精品iOS DeveloperiOS技术点
【iOS开发】路由+协议打造极简 table view 和 co

【iOS开发】路由+协议打造极简 table view 和 co

作者: Brant白叔 | 来源:发表于2017-12-19 18:08 被阅读250次

    好久没有写东西了,今天来分享一下最近在项目中对UITableView的一种优化写法。

    先来看一下效果

    效果图

    上面这个页面对应的ViewController的代码是这样的, Demo地址在文章的末尾:

    
    #import "ViewController.h"
    #import "YTTableView.h"
    #import "ViewModel.h"
    
    @interface ViewController ()
    
    @property (nonatomic, strong) YTTableView *tableView;
    @property (nonatomic, strong) ViewModel *viewModel;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        [self.view addSubview:self.tableView];
        self.tableView.frame = self.view.bounds;
        
        [self bindActions];
        
        self.tableView.sections = self.viewModel.sections;
    }
    
    - (void)bindActions {
        
        /*
         
         关于事件处理:
         1、建议项目用路由,cell的事件直接在cell内部处理掉。
         2、如果不用路由,如果cell上有个button什么的,点击要处理,可以在cell的view model里面声明对应的RACSignal。再进行订阅。点击button的时候,发送事件就可以处理了。
         3、cell的点击处理还可以用下面的这个didSelectRow来处理。
         
         */
        self.tableView.didSelectRow = ^(id viewModel, NSString *sectionKey) {
            // 点击事件在这里处理
        };
    }
    
    #pragma mark - lazy load
    
    - (YTTableView *)tableView {
        if (!_tableView) {
            _tableView = [[YTTableView alloc] init];
            _tableView.backgroundColor = [UIColor colorWithRed:0xef/255.0 green:0xef/255.0 blue:0xef/255.0 alpha:1];
            _tableView.tableFooterView = [UIView new];
            _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        }
        
        return _tableView;
    }
    
    - (ViewModel *)viewModel {
        if (!_viewModel) {
            _viewModel = [ViewModel new];
        }
        
        return _viewModel;
    }
    
    @end
    
    

    适用场景

    任何用tableView的地方都可以用。

    一般的开发写法

    要在ViewController里面引入所有类型的cell,在cellForRow方法里面使用。注册cell使用。heightForRow方法也是各种判断(前面写了一篇文章减少判断的【iOS开发】UITableView和UICollectionView多种类型cell处理,更好地组织代码),增加或者减少某个类型的cell的时候,得去ViewController里面的好几个地增加或者减少代码。

    YTTableView

    优点

    • 完全解耦cell和view controller。

    • 方便版本迭代:新版本有新的样式或是要添加新的section 什么的,都可以不用改动viewController。

    • cell有极高的可重用性,实现了对应的协议后,任何地方都可以用。

    • 不需要修改ViewController里面的代码。

    • 任何的修改都可以在一个地方完成。

    • 集成了table view的分隔线,可以任意调整分隔线。section的第一条和最后一条分隔线可以分开设置。

    cell的事件处理

    1. 建议项目用路由,cell的事件直接在cell内部处理掉。
    2. 如果不用路由,如果cell上有个button什么的,点击要处理,可以在cell的view model里面声明对应的RACSignal。再进行订阅。点击button的时候,发送事件就可以处理了。
    3. cell的点击处理还可以用YTTableView暴露的didSelectRow来处理。

    集成使用

    把YTTableView相关代码拉到项目中,pod支持找时间加上去。

    注意的点:

    1. 如果用YTTableView中的自定义的分隔线,记得把table view本来的分隔线去掉。

    2. cell都要有一个对应的cell view model。

    3. cell 要实现YTCellProtocol协议。

    4. cell view model 要实现 YTTableCellViewModelProtocol协议。

    协议说明

    • YTCellProtocol
      table view的cell都要实现这个接口,接口提供配置数据的方法和注册cell的方法。
    /**
     cell 的接口
     提供一个配置cell的ViewModel的方法
     */
    @protocol YTCellProtocol <NSObject>
    
    @required
    
    
    /**
     通过 view model 来配置cell, table view 的数据源里面装的都会是 view model
     
     @param viewModel cell 对应的 view model
     */
    - (void)configCellWithViewModel:(id)viewModel;
    
    
    @end
    
    • YTTableCellViewModelProtocol
      table view cell 对应的view model 都要实现这个接口,实现返回cell高度的方法和cell的复用id
    /**
     UITableViewCell 对应的ViewModel 的协议
     */
    @protocol YTTableCellViewModelProtocol <NSObject>
    
    @required;
    /**
     返回cell的高度, 这个方法是在view model中实现,view model中有cell的全部数据,所以这里可以通过数据计算高度,或者直接返回固定高度
     
     @return cell的高度
     */
    - (CGFloat)cellHeight;
    
    
    /**
     返回cell的复用id
     
     @return cell的复用id
     */
    + (NSString *)identifier;
    
    
    /**
     注册cell
    
     @param table 要注册到的table view
     */
    + (void)registerFor:(UITableView *)table;
    
    @end
    

    Section类说明

    @interface YTTableViewSection : NSObject
    
    /**
     用来标识section的类型,要保证每个section的都不同
     代理方法里面如果要做特殊处理会用到,所以不能相同
     */
    @property (nonatomic, copy) NSString *sectionKey;
    
    
    /**
     section 里面 row 的 view model 集合
     */
    @property (nonatomic, copy) NSArray *viewModels;
    
    
    /**
     返回这个section有多少row,这个不用设置,在设置viewModels时,会自动设置
     */
    @property (nonatomic, readonly) NSInteger numberOfRows;
    
    
    /**
     是否自动添加分隔线
     */
    @property (nonatomic) BOOL autoSeparator;
    // 分隔线颜色 默认:#E6E6E6
    @property (nonatomic, strong) UIColor *separatorColor;
    @property (nonatomic, strong) UIColor *separatorBackgroundColor;
    // 分隔线左边缩进
    @property (nonatomic) CGFloat separatorLeftInset;
    // 分隔线右边缩进
    @property (nonatomic) CGFloat separatorRightInset;
    // 分隔线的高度 默认1px
    @property (nonatomic) CGFloat separatorHeight;
    
    // section头部分隔线 不受separatorInset影响
    @property (nonatomic) BOOL sectionTopSeparator;
    @property (nonatomic) CGFloat topSeparatorHeight;
    @property (nonatomic, strong) UIColor *topSeparatorColor;
    
    // section尾部分隔线 不受separatorInset影响
    @property (nonatomic) BOOL sectionBottomSeparator;
    @property (nonatomic) CGFloat bottomSeparatorHeight;
    @property (nonatomic, strong) UIColor *bottomSeparatorColor;
    
    - (instancetype)initWithSectionKey:(NSString *)key viewModels:(NSArray *)viewModels;
    

    Cocoapods支持

    如果觉得可以就给个Star。
    Github Repo

    相关文章

      网友评论

        本文标题:【iOS开发】路由+协议打造极简 table view 和 co

        本文链接:https://www.haomeiwen.com/subject/xajiwxtx.html