您的位置:首页 > 产品设计 > UI/UE

UITableView 以及 UITableViewCell 的重用机制

2015-07-14 09:40 591 查看

直接上代码:

//
//  RootViewController.m
//
//

#import "RootViewController.h"
#import "DetailViewController.h"

/*
    TableView 作为一个空表,自身并不确定项目中需要展示的行数,显示的内容以及单元格的样式,所以需要通过代理来获取;
    TableView 对应的试图控制器需要遵守 UITableViewDataSource 协议,并实现两个必须实现的协议方法
    1、每一个分区需要展示多少行(通航协议方法返回值提供给 TableView )
    2、指定分区指定行所需要的单元格对象(通过协议方法返回值提供给 TableView ) TableView 真正展示数据的视图为其所管理的单元格,所以代理对象在协议方法中创建单元格的同时需要为单元格提供数据。
 */
@interface RootViewController ()<UITableViewDataSource, UITableViewDelegate>

@property (nonatomic, retain) NSArray *titles; //保存分区区头标题的数组

@end

@implementation RootViewController

- (void)dealloc {
    [_titles release];
    [super dealloc];
}

- (NSArray *)titles {
    if (!_titles) {
        self.titles = @[@"A", @"B", @"C", @"D", @"E", @"F"];
    }
    return _titles;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    //创建 tableView 并指定样式
    UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];

    //设置分割线的样式
    tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
    //设置分割线的颜色
    tableView.separatorColor = [UIColor blueColor];
    //设置分割线的内边距,分别为上,左,下,右
    tableView.separatorInset = UIEdgeInsetsMake(0, 10, 0, 10);
    //设置行高
    tableView.rowHeight = 50;

    //为 tableView 指定数据源代理。
    tableView.dataSource = self;
    //为 tableView 指定代理对象,做外观控制。
    tableView.delegate = self;

    [self.view addSubview:tableView];
    [tableView release];

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

//这个代理方法先执行,只有先确定了行数才能为每个单元格添加内容。
- (NSInteger)tableView:(UITableView *)tableView
 numberOfRowsInSection:(NSInteger)section {

    if (section == 0) {
        return 4;
    }
    return 20;//行数
}

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//    UITableViewCell *aCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil];
//    //为指定分区指定行设置显示的内容
//    aCell.textLabel.text = [NSString stringWithFormat:@"{%ld,%ld},☺☺☺", indexPath.section, indexPath.row];
//    aCell.detailTextLabel.text = @"单元格的子标题";
//   
//    //设置单元格被选中的样式, ios 7.0 以后 选中的样式一共只有两种可用 ,一种是选中没有样式, 一种是选中后显示灰色。
//    aCell.selectionStyle = UITableViewCellSelectionStyleDefault;
//   
//    // 辅助视图样式
//    aCell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
//   
//    // Cell 自带的 ImageView 是以单元格的高度为基准,按照图片的原始比例进行的缩放。
//    aCell.imageView.image = [UIImage imageNamed:@"shizi"];
//   
//    if (indexPath.row == 2) {
//        aCell.imageView.image = [UIImage imageNamed:@"gril"];
//    }
//    //开关
//    UISwitch *aSwitch = [[UISwitch alloc] init];
//    aCell.accessoryView = aSwitch;
//    //微调器
////    UIStepper *aStepper  = [[UIStepper alloc] init];
////    aCell.accessoryView = aStepper;
//   
//    return [aCell autorelease];

    /*
     重用机制是 tableView 提供的用于控制和优化内存的解决方案,其原理为:根据 tableView 的大小以及行高创建指定个数的单元格,当产生滑动时,一些暂时滑出 tableView 的单元格就会进入到 tableView 得重用队列被保存下来,等待下次继续使用,那么代理对象通过当前方法为 tableView 提供单元格对象时优先根据前指定的重用标识符获取重用队列中是否有可用的单元格,如果有,则重新为单元格添加数据,如果没有则创建新的单元格,然后添加数据,返回给表视图让其管理显示。
     */

    // 1、定义静态重用标识字符串。
    static NSString *identifier = @"CELL";
    // 2、根据给定的重用标识符从表视图的重用队列中获取可用单元格。
    UITableViewCell *aCell = [tableView dequeueReusableCellWithIdentifier:identifier];
    // 3、如果表视图的重用队列中没有可重用的单元格,则需要创建新的单元格。
    if (!aCell) {
        aCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
        // if 语句中可以为单元格一些通用属性赋值,例如可以为其辅助视图类型赋值,表示所有单元格的赋值样式都一致。
        aCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    }
    //4、为单元格相关属性赋值,显示数据。
    aCell.textLabel.text = [NSString stringWithFormat:@"%@,%ld", aCell.textLabel.text, indexPath.row];;

    //单元格进入到重用队列后其子视图和展示的数据并不会被清除,从重用队列中得到的单元格需要重新利用,所以不能在当前方法无限制的为单元格添加子视图,会导致重影问题以及内存问题,相反我们可以通过子类化单元格的形式自定义其外观和展示。
//    UILabel *aLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 0, 200, 200)];
//    aLabel.textAlignment = NSTextAlignmentCenter;
//    aLabel.font = [UIFont systemFontOfSize:40];
//    aLabel.text = [NSString stringWithFormat:@"%d", arc4random() % 10 ];
//    [aCell addSubview:aLabel];
//    [aLabel release];

    //5、返回单元格给表视图
    return aCell;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    //表视图默认拥有一个分区,我们可以通过此协议方法设置分区的个数
    return 6;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {

    //为每一个分区指定分区区头标题
    return self.titles[section];
}

- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
    //为每一个分区指定分区区尾标题
    return @"区尾 标题";
}

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    //设置表视图分区的快速索引数组,该数组的内容需要与分区的区头标题一致,才可通过触摸快速切换分区。
    return self.titles;
}

//自定义区头视图,需要先通过协议方法设置区头视图的高度,再为表视图指定对应的视图的对象。
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 40;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UIView *view = [[UIView alloc] init];
    view.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1];
    return [view autorelease];
}

//自定义区尾视图,需要先通过协议方法设置区尾视图的高度,再为表视图指定对应的视图的对象。
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    return 20;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    UIView *view = [[UIView alloc] init];
    view.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1];
    return [view autorelease];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    //除了 tableView 的 rowHeight 属性可以设置固定高度,我们还可以通过此协议方法根据需要展示的内容来设置各行的行高。
    return arc4random() % 71 + 30;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    //当点击某个单元格是会响应该方法,可以在此方法中做出对应的实现,比如创建新的视图控制器,对象通过导航控制器切换显示。
    DetailViewController *detailVC = [[DetailViewController alloc] init];
    detailVC.title = [NSString stringWithFormat:@"第%ld分区, 第%ld行", indexPath.section, indexPath.row ];
    [self.navigationController pushViewController:detailVC animated:YES];
    [detailVC release];
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: