Xcode控件使用笔记四:UITableView

UITableView的两种内置样式:UITableViewStylePlain  和 UTTableViewStyleGrouped(分组)

1、分组例子 : storyboard选择一个UITableView,style设置为Grouped

//  ViewController.m
#pragma mark - 数据源方法
#pragma mark 一共有多少组数据
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 2;
}
#pragma mark 第section组有多少行数据
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
}
#pragma mark 返回每一行显示的具体数据
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 组 indexPath.section
    // 行 indexPath.row
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
    // 设置cell上面显示的文本数据
    cell.textLabel.text = city;
    
    return cell;
}
#pragma mark 第section组的标题 
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
}
#pragma mark
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
}
#pragma mark 右侧快捷分组
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    return self.provinces;
    //return @[@"A", @"B", @"C"];
}

2、单组例子 

UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil];
    
    // 图片的文件名
    NSString *name = [NSString stringWithFormat:@"00%d.png", indexPath.row + 1];
    
    // 设置左边的图标
    cell.imageView.image = [UIImage imageNamed:name];
    // 设置主标题
    cell.textLabel.text = @"123213213";
    // 设置副标题
    cell.detailTextLabel.text = @"详细描述------";
    
    // 设置cell的右边箭头样式 ->
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    
    return cell;

#pragma mark - 代理方法
#pragma mark 选中了某一行就会调用
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //NSLog(@"--------%d", indexPath.row);
    
    // 1.获得被点击这行对应的产品信息
    MJProduct *p = self.data[indexPath.row];
    
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"产品信息" message:nil
                                                   delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
    
    // 保存点击的行号
    alert.tag = indexPath.row;
    
    // 设置alertView的样式
    alert.alertViewStyle = UIAlertViewStylePlainTextInput;
    
    // 取出文本输入框
    [alert textFieldAtIndex:0].text = p.name;
    
    // 显示对话框
    [alert show];
}

#pragma mark - ALertView代理方法
#pragma mark 点击了AlertView的某个按钮时调用
/*
 
 刷新数据:
 1> 更改模型属性
 2> 刷新UI界面(reloadDat43a)
 */
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1)
    { // 点击了确定按钮
        // 1.取得文本框的文字
        NSString *name = [alertView textFieldAtIndex:0].text;
        //NSLog(@"%@", name);
        
        // 2.更新数据(alertView.tag 就是 行号)
        MJProduct *p = self.data[alertView.tag];
        //NSLog(@"%@", p.name);
        p.name = name;
        
        // 3.刷新界面
        /*
         重新加载数据:
         重新向数据源请求数据(重新调用数据源的相应方法)
         
         会刷新所有的数据
         *///[self.tableView reloadData];
        
        // 局部刷新
        NSIndexPath *path = [NSIndexPath indexPathForRow:alertView.tag inSection:0];
        [self.tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationLeft];
    }
}

3、性能优化

1)缓冲池--重用机制:

cellForRowAtIndexPath方法根据新增一定数量的cell对象( view的高度/cell的高度),不会一下子新增所有(关键点在"一个屏幕显示的cell数量"是有限的

dequeueReusableCellWithIdentifier,从字面上理解是“出列的可重用的cell”

reuse机制就是这样。当cell需要显示的时候,从queue里面找,找到了,设置一下内容,显示出来
滚动界面当有cell被移出屏幕时,把这个cell丢到queue里面
显示新的cell时,如果有“相同类型”(identifier)的cell,就从队列拿一个出来,设置数据,显示出来
至于queue里面会有多少cell,这个会自动控制

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    // 0.用static修饰的局部变量,只会初始化一次< # # >
    static NSString *ID = @"Cell";
    
    // 1.拿到一个标识先去缓存池中查找对应的Cell
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    
    // 2.如果缓存池中没有,才需要传入一个标识创建新的Cell
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
    }
    
    // 3.覆盖数据
    cell.textLabel.text = [NSString stringWithFormat:@"fdsfdsf-%d", indexPath.row];
    NSLog(@"---cellForRowAtIndexPath--%p--%d",cell,indexPath.row);
    
    return cell;

}

4、编辑模式

#pragma mark 提交编辑操作(点击了"删除"或者"+"按钮)时调用
// 实现了这个方法,就有左划删除功能
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle  forRowAtIndexPath:(NSIndexPath *)indexPath
{
    //NSLog(@"------commit---%d", indexPath.row);
    
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // 删除
        // 1.更改数据(删除本行的数据)
        [self.mydata removeObjectAtIndex:indexPath.row];
        
        // 2.刷新UI界面
        //[tableView reloadData];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
    } else {
        // 添加
        
        // 1.更改数据(添加数据)
        // [self.mydata addObject:@"hahahhahah"];添加到最后面去了
        // 插入数据到本行的后面
        [self.mydata insertObject:@"新添加的数据...." atIndex:indexPath.row + 1];
        
        // 2.刷新UI界面
        //[tableView reloadData];
        
        // 刷新指定行(个数不变)
        //[tableView reloadRowsAtIndexPaths:<#(NSArray *)#> withRowAnimation:<#(UITableViewRowAnimation)#>];
        // 删除指定行
        //[tableView deleteRowsAtIndexPaths:<#(NSArray *)#> withRowAnimation:<#(UITableViewRowAnimation)#>];
        // 插入新的行
        
        NSIndexPath *newPath = [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:0];
        [tableView insertRowsAtIndexPaths:@[newPath] withRowAnimation:UITableViewRowAnimationTop];
    }
    /*
     
     */
}

#pragma mark 开启编辑模式时,用到的移动方法
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
    // 取出即将要删除的数据
    NSString *data = self.mydata[sourceIndexPath.row];
    
    // 删除需要移动的那一行
    [self.mydata removeObject:data];
    
    // 插入之前删除的数据
    [self.mydata insertObject:data atIndex:destinationIndexPath.row];
    
    //NSLog(@"%d --> %d", sourceIndexPath.row, destinationIndexPath.row);
}

#pragma mark - 代理方法
#pragma mark 当tableview开启编辑模式就会调用
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //return indexPath.row%2 ? UITableViewCellEditingStyleDelete : UITableViewCellEditingStyleInsert;
    return tableView.tag;
}

//UITableViewCellEditingStyle _style;

#pragma mark - 监听item的点击
#pragma mark 删除
- (IBAction)remove
{
    self.tableView.tag = UITableViewCellEditingStyleDelete;
    
    //_style = UITableViewCellEditingStyleDelete;
    
    // 0.取出当前的编辑状态
    BOOL edt = self.tableView.editing;
    
    // 1.开启编辑模式
    //self.tableView.editing = YES;
    //[self.tableView setEditing:YES];
    // 带有动画效果
    [self.tableView setEditing:!edt animated:YES];
}

- (IBAction)add
{
    self.tableView.tag = UITableViewCellEditingStyleInsert;
    //_style = UITableViewCellEditingStyleInsert;
    
    //NSLog(@"add------");
    // 0.取出当前的编辑状态
    BOOL edt = self.tableView.editing;
    
    // 1.开启编辑模式
    [self.tableView setEditing:!edt animated:YES];
}

 一、删除\添加:

 1.开启编辑模式

 [self.tableView setEditing:YES animated:YES];

 2.实现数据源的某个方法

 tableView:commitEditingStyle:forRowAtIndexPath:

 3.下面方法的返回值决定编辑模式是添加还是删除

 - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath

 二、排序:

 实现下面的方法即可:

 tableView:moveRowAtIndexPath:toIndexPath:

 三、4个刷新UI界面的方法

 1.添加新的行

 [tableView insertRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationTop];

 2.删除指定的行

 [tableView deleteRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationTop];

 3.局部刷新指定的行

 [tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationTop];

 4.整体刷新所有的行

 [tableView reloadData];



发布了28 篇原创文章 · 获赞 7 · 访问量 9万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章