数据源(dataSource)和代理(delegate)
•UITableView需要一个数据源(dataSource)来显示数据,UITableView会向数据源查询一共有多少行数据以及每一行显示什么数据等。没有设置数据源的UITableView只是个空壳。凡是遵守UITableViewDataSource协议的OC对象,都可以是UITableView的数据源
•
•通常都要为UITableView设置代理对象(delegate),以便在UITableView触发一下事件时做出相应的处理,比如选中了某一行。凡是遵守了UITableViewDelegate协议的OC对象,都可以是UITableView的代理对象
•
•通常情况下,会让控制器充当UITableView的dataSource和delegate

 

关于UITableView性能优化使用的提示

创建UITableViewCell时,必须设置一个唯一标示
去缓存池取出UITableViewCell时,必须传入一个标示

 

UITableView的编辑模式

UITableView属有个editing性,当设置为YES时,可以进入编辑模式。在编辑模式下,可以管理表格中的行,比如改变行的排列顺序、增加行、删除行,但不能修改行的内容
开启编辑模式的方法:
@property(nonatomic,getter=isEditing) BOOL editing;
- (void)setEditing:(BOOL)editing animated:(BOOL)animated;

 

在UITableView中删除或添加行

1. 开启表格的编辑模式

2. 实现UITableViewDataSource的方法:
- (void)tableView:commitEditingStyle:forRowAtIndexPath:

3. 实现UITableViewDelegate的方法:
- (UITableViewCellEditingStyle)tableView: editingStyleForRowAtIndexPath:

注意:如果不实现该方法,默认将编辑模式视为删除

 

 

移动UITableView的行

1. 开启表格的编辑模式
  BOOL isEditing = _tableView.isEditing;
    
    // 1. 开启表格的编辑模式
    [_tableView setEditing:!isEditing animated:YES];

2. 实现UITableViewDataSource的方法: - (void)tableView:moveRowAtIndexPath:toIndexPath:

 

#pragma mark - 移动表格行
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
//    NSLog(@"%@", _dataList);
    // 通过Log我们发现,在此方法中,我们只需做跟新数据的工作即可
    // 界面上的动画,以及表格内容的更新,我们都不需要去处理
    // 1. 取出用户选中行的数据
    NSString *data = _dataList[sourceIndexPath.row];
    // 2. 把用户选中的数据删除
    NSLog(@"删除前的总数是 %d", _dataList.count);
    [_dataList removeObjectAtIndex:sourceIndexPath.row];
    NSLog(@"删除后的总数是 %d", _dataList.count);
    // 3. 找到用户要插入行的位置,将选中行插入到数组中
    [_dataList insertObject:data atIndex:destinationIndexPath.row];
    
    NSLog(@"%@", _dataList);
}

 

注意:只要实现了该方法,即可实现表格移动

 

四种刷新表格数据的方法

// 新增表格数据
[tableView insertRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationTop];
// 删除表格数据
[tableView deleteRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationRight];
// 局部刷新指定的行
[tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationMiddle];
// 刷新全部表格数据,如果能够准确确定被修改的数据行,就不要用此方法
[tableView reloadData];
UITabelView常用属性

分隔线属性
separatorStyle 分隔线样式
separatorColor 分隔线颜色
选中属性
allowsSelection 允许选中
allowsMultipleSelection 允许多选
行数
indexPathsForSelectedRows 当前选中行数
indexPathsForVisibleRows 当前可见行数
背景
backgroundView    背景视图
selectedBackgroundView 选中时的背景视图
另外,UITableViewCell的selectionStyle属性可设置被选中时的背景颜色:
UITableViewCellSelectionStyleNone  没有颜色
UITableViewCellSelectionStyleBlue  蓝色(默认)
UITableViewCellSelectionStyleGray  灰色
#import "ViewController.h"


@interface ViewController ()

// 数据数组
@property (nonatomic, strong) NSMutableArray *dataList;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // 初始化数据
    _dataList = [NSMutableArray arrayWithCapacity:30];
    for (NSInteger i = 0; i < 30; i++) {
        NSString *string = [NSString stringWithFormat:@"itcast-%03d", i];
        
        [_dataList addObject:string];
    }
    
    /*
     以下代码演示MyTabel类的交互
     */
    MyTable *myTable = [[MyTable alloc]init];
    [myTable setDelegate:self];
    [myTable updateData];
//    [myTable setType:0];
}

#pragma mark - MyTable代理方法
- (NSInteger)tellMeType:(MyTable *)myTable
{
    return arc4random_uniform(10) % 2 == 0;
}

#pragma mark - 数据源方法
#pragma mark 数据行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _dataList.count;
}

#pragma mark 每一行显示的内容
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 1. 创建一个静态表格标示字符串,定义静态变量时,变量首字母要大写
    static NSString *CellIdentifier = @"Cell";
    // 2. 从缓存池查找是否有可用的表格行对象
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
    // 3. 如果没有找到可重用单元格对象,实例化新的单元格
    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
    }
    
    NSLog(@"单元格指针(%d) %p", indexPath.row, cell);
    
    // 4. 设置单元格内容
    cell.textLabel.text = _dataList[indexPath.row];
    cell.detailTextLabel.text = @"详细信息";
    
    return cell;
}

#pragma mark - 移动表格行
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
//    NSLog(@"%@", _dataList);
    // 通过Log我们发现,在此方法中,我们只需做跟新数据的工作即可
    // 界面上的动画,以及表格内容的更新,我们都不需要去处理
    // 1. 取出用户选中行的数据
    NSString *data = _dataList[sourceIndexPath.row];
    // 2. 把用户选中的数据删除
    NSLog(@"删除前的总数是 %d", _dataList.count);
    [_dataList removeObjectAtIndex:sourceIndexPath.row];
    NSLog(@"删除后的总数是 %d", _dataList.count);
    // 3. 找到用户要插入行的位置,将选中行插入到数组中
    [_dataList insertObject:data atIndex:destinationIndexPath.row];
    
    NSLog(@"%@", _dataList);
}

#pragma mark 表格控件提交编辑模式
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"编辑样式 %d", editingStyle);
    
    // 判断表格是否需要删除数据
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // 1. 删除_dataList中的数据
        [_dataList removeObjectAtIndex:indexPath.row];
        NSLog(@"%@", _dataList);
        
        // 2. 更新表格显示
        [_tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight];
    } else {
        // 1. 在_dataList中插入数据
        //      可以在传入参数indexPath.row + 1 的位置插入数据
        //      也就是用户当前选中行的下一行
        [_dataList insertObject:@"新增数据" atIndex:(indexPath.row + 1)
         ];
        NSLog(@"%@", _dataList);
        
        // 2. 更新表格显示
        // 界面上添加数据的newPath.row应该是参数indexPath.row + 1
        NSIndexPath *newPath = [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:0];
        [_tableView insertRowsAtIndexPaths:@[newPath] withRowAnimation:UITableViewRowAnimationTop];
    }
}

#pragma mark 返回表格的编辑样式:删除、新增
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
//    NSLog(@"告诉表格编辑样式");
    
    return _tableView.tag;
}

#pragma mark - Actions
#pragma mark  删除操作
- (IBAction)remove:(id)sender
{
    [_tableView setTag:UITableViewCellEditingStyleDelete];
    
    // 再次点击删除按钮,要恢复到正常浏览模式
    // 编辑|浏览
    // 根据表格的isEditing属性可以判断出当前是否处于编辑状态
    // 如果是编辑状态,则改为浏览状态,否则,改为编辑状态
    BOOL isEditing = _tableView.isEditing;
    
    // 1. 开启表格的编辑模式
    [_tableView setEditing:!isEditing animated:YES];
}

#pragma mark 添加操作
- (IBAction)add:(id)sender
{
    /**
     新增或者删除操作方法的执行顺序
     
     1. 由按钮开启编辑样式 setEditing
     2. 表格会对屏幕上每一个行调用 tableView:editingStyleForRowAtIndexPath:
        告诉当前的行是什么编辑样式(新增或是删除)
        注意:如果不实现这一方法,默认都是删除样式
     3. 当用户点击屏幕上相关按钮:加好或者减号,会调用:
        tableView:commitEditingStyle:forRowAtIndexPath:
        方法,控制器需要在此方法中更新数据,同时更新界面
     */
    
    // 利用表格的tag属性记录当前的编辑样式是新增
    [_tableView setTag:UITableViewCellEditingStyleInsert];
    
    // 判断表格当前是否是编辑模式,如果是,进入浏览状态,如果不是,进入编辑状态
    BOOL isEditing = _tableView.isEditing;
    
    NSLog(@"开启编辑模式");
    
    // 开启表格的编辑模式
    [_tableView setEditing:!isEditing animated:YES];
}

@end

 

 
posted on 2015-02-07 22:55  HJiang  阅读(220)  评论(0编辑  收藏  举报