UITableView介紹 之 基本用法
UITableView簡介
UITableView是我們ios開發中最常用的一個控制元件,學會UItableView的使用對我們的開發工作也是相當重要。
基本用法
使用Xcode新建一個空專案,在預設的UIViewController中顯示我們的UITableView,首先在viewDidLoad方法中初始化tableView
UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:tableView];
我在開發中的習慣是新創建出來的view立即新增到父中去以免後面會忘掉,除非有一些其他的邏輯要處理。一個UITableView要能顯示一般需要控制器實現兩個代理方法UITableViewDataSource, UITableViewDelegate前一個代理方法是為tableView提供資料,後一個主要是處理和tableView屬性相關的比如:行高、cell的點選等。
分別檢視這兩個代理方法你會發現UITableViewDataSource的代理方法有兩個是必須實現的,而UITableViewDelegate所有的方法都是可選的,那麼建立一個tableView的最簡單的方式就是實現DataSource中的兩個方法就可以了。
@required
// 返回一個UITableView的總行數
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
// 返回每一個cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
需要說明的是這裡的tableView是單組的,廢話不多說建立一個簡單tableView的程式碼如下:
//
// ViewController.m
// UITableViewDemo
//
// Created by code_xq on 16/2/28.
// Copyright © 2016年 code_xq. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()<UITableViewDataSource >
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:tableView];
tableView.dataSource = self;
}
#pragma mark - 代理方法<UITableViewDataSource>
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 100;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 建立cell
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
cell.textLabel.text = [NSString stringWithFormat:@"cell--%ld", indexPath.row];
return cell;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
需要說明的cell的建立方法init方法一共有兩個引數,第一個引數是一個列舉蘋果官方為我們提供了幾種cell的顯示模式,第二個引數是一類cell的統一標示,cell重用時會用到。
tableView中cell的重用
考慮到資料量大的情況,不可能有一萬條資料就按照上面的方式建立一萬個cell這樣會非常吃記憶體,效率也會大大降低,於是蘋果為我們實現了一套cell重用機制,一次性只建立有限個cell顯示在螢幕上,滑動時要用到的話再去建立,把離開螢幕中看不見cell放到一個快取集合中去,當下次要建立時先從集合中取,如果有就不用建立了,這樣會大大提高tableView的效能。
- 傳統做法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 定義static變數,由於本方法會被呼叫多次如果用區域性變數的話有點浪費
static NSString *const ID = @"cell";
// 先從快取中找,如果沒有再建立
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
cell.textLabel.text = [NSString stringWithFormat:@"cell--%ld", indexPath.row];
return cell;
}
因為這段程式碼經常會用到,我習慣把他放到我的Xcode的程式碼倉庫中這是開發中的一個小技巧。
- 新做法
不用寫if判斷,可以直接在ViewDidLoad方法中對cell進行註冊,最後直接從快取中取
#import "ViewController.h"
// 定義static變數
static NSString *const ID = @"cell";
@interface ViewController ()<UITableViewDataSource>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:tableView];
tableView.dataSource = self;
// cell註冊
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID];
}
#pragma mark - 代理方法<UITableViewDataSource>
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 100;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// // 定義static變數,由於本方法會被呼叫多次如果用區域性變數的話有點浪費
// static NSString *const ID = @"cell";
// 先從快取中找,如果沒有再建立
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
// if (!cell) {
// cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
// }
cell.textLabel.text = [NSString stringWithFormat:@"cell--%ld", indexPath.row];
return cell;
}