TableView

weixin_34232744發表於2017-08-18

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"]];

相關文章