TableView

作者: 猪队友小L | 来源:发表于2017-08-18 16:59 被阅读8次

    TableView怎么用

    TableView中可以添加TableCell,而其主要通过两个协议进行Table的管理 <UITableViewDataSource,UITableViewDelegate>,可以通过阅读头文件详细了解

    UITableViewDataSource

    该协议中的两个函数是Table管理Cell必须的,分别是Table有多少行和每行是什么Cell

    @required
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
    

    UITableViewDelegate

    这个协议中是主要定义了cell的选中功能函数,也包括一些其它optional功能,如果仅仅是展示性质的cell,可以不用用到

    // Selection
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
    

    TableView中Cell的复用

    TableView中cell的复用是十分十分重要的一个知识点,几乎所有面试都会问吧

    什么叫复用

    就是我有100行cell,但是不可能一页(Screen的高度)显示完,那么我可以制造一种假象,仿佛我有100行,但是实际只有20行,每当用户进行滑动,我就把滑出屏幕的cell,重新拼接到屏幕下方,展示给用户

    不复用的实现

    首先看不采用复用方法的Cell生成,遵循UITableViewDataSource生成cell

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        NSString *cellIdentifier =  [NSString stringWithFormat:@"cell%tu",indexPath.row];
        UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        return cell;
    }
    

    由以上函数可知,这是传统思维,给予每个cell一个identifer然后通过后缀的行数返回给Table每个cell,这样如果我有100行,我就有100个cell在内存里,这样无疑是十分消耗内存的

    复用的实现

    复用就是,我使用一个cellIdentifer展示100个cell,那么就要用到dequeueReusableCellWithIdentifier:函数

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        static NSString *cellIdentifier =  @"cellID";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        if (cell == nil) {
            cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        }
        return cell;
    }
    

    以上的复用过程主要过程是

    1. 我在静态区声明一个cellIndentifer,不用每次执行到这里都初始化一个NSString
    2. 然后用dequeueReusableCellWithIdentifier:函数根据Indentifer从一个复用池(cocoa框架自带的)里取cell
    3. 如果取不到(cell == nil),就重新初始化一个

    那么如果采用复用方法,100行的cell会发生什么

    1. 假设一屏有10行
    2. 不可否认的是我至少需要10个长的一样的cell
    3. 那么前10行通过tableView:cellForRowAtIndexPath:时,都会因为复用池中没有identifer为"cellID"的cell从而去初始化
    4. 此时用户下滑,第1行移出屏幕,第11行移入屏幕
    5. 第1行移出屏幕,identifer为"cellID"的一个cell进入复用池
    6. 第11行移入屏幕时,经过tableView:cellForRowAtIndexPath:内时,通过dequeueReusableCellWithIdentifier:函数从复用池中取出刚刚第1行放入的cell,完成复用
    7. 如果此时又上滑,第11行移出屏幕,cell被放回复用池又被第一行取走

    需要注意的是,通常为了保障动画的流畅,10行可能需要12-15个cell进行复用

    Cell也可以用在普通View中

    由于Cell本身就是一个View,所以不一定非得加载在Table中,普通的View也可以直接用

    UITableViewCell *cell = [[UITableViewCell alloc]init];
    [self.view addSubview:cell];
    

    但是由于其不在UITableViewDelegate的tableView:didSelectRowAtIndexPath:中实现选中功能,所以其本身不能交互,需要进行设置

    [cell setUserInteractionEnabled:YES];
    

    而且又由于其不是button,并不能touchUpInside,所以需要通过添加手势来交互

    UITapGestureRecognizer *gestureOnCell = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapGestureOnAlbumCell:)];
    [cell addGestureRecognizer:gestureOnCell];
    

    感觉并不好用呢╮<(=╯-╰=)>╭ 但是可以省去自定义view,可以利用系统的样式,减少开发工作

    [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
    [cell.textLabel setText:@"cellTitle"];
    [cell.imageView setImage:[UIImage imageNamed:@"account_headImg_picture"]];

    相关文章

      网友评论

          本文标题:TableView

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