iOS学习随笔-UITableView的那些事

UITableView可以说是非常广泛的出现在各大app中的类了。今天算是专心的做了一天的列表视图,实现了一些基本的功能。

在开始之前,先要弄明白UITableViewDataSource这个协议都要实现哪写方法。苹果官方的API就贴在文末了


首先关注两个Required的方法:cellForRowAtIndexPath和numberOfRowsInSection

其中numberOfRowsInSection就是返回数据的组数就不多说了,只要注意row是从0开始的就好

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//#warning Incomplete implementation, return the number of rows
    return [[[User sharedUser] allItems] count] + 1;
}
顺便提一下相似的另一个可选方法numberOfSectionsInTableView,默认生成这个方法时会返回0,这个必须改掉,因为这个方法返回的值是Sections,再少的data source都有一个Sections。Sections可以理解为通讯录或者字典中的首字母的节

创建:

对于cellForRowAtIndexPath,这个方法主要做了这些事:  

1、创建一个UITableViewCell的对象

2、获取所需的数据模型的对象的数据

3、得到信息,将信息给到cell以后返回这个cell


然而,iOS设备内存有限,不可能同时为所有数据条目准备一份cell对象,所以就需要cell对象的重用,每个cell在不被用户看到后会被丢到一个cell的对象池中等待被重用,当tableview对象要求data source返回某个cell时,只要从池中取到cell对象,再宠幸配置数据就可以返回了,在cellForRowAtIndexPath我们就做了这件事。

重用有两种方法

方法一:

使用 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];

这种方法,用到的参数是一个NSString类型的cell的标签。标签的用途是因为可能存在同一张表中需要不同样式的cell,只有同种类的cell才能互相重用。所以对于同种对cell,我们都要给它一个标签来标明它的种类。标签名一般为类名。

因为初始状态下cell对象池为空,所以一开始这个函数可能返回nil,所以一般我们会这么写

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
    if(!cell){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"UITableViewCell"];
	//数据配置操作... 
    }


方法二:

使用

UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:@"UITableViewCell"forIndexPath:indexPath];

与上一种方法对比,多出的类型为(NSIndexPath *)参数IndexPath用来确定cell的位置。对于这种方法,在所需cell对象为空(对象池中没有与自己标签相同的对象)的情况下会自动生成新对象,也就是说不会有nil的出现,比上一种方法省略了判断后的函数体

然而这种方法必须在使用前对标签进行注册,否则程序会crash

//注册cell
    [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"UITableViewCell"];
    [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"noMore"];



然后是一些可选的方法,涉及到了表格的删除,移动等操作


删除:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;

这个方法中可以完成的操作有删除和插入,此处以插入为例

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    //如果tableview 请求确认删除操作
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        if(indexPath.row < [[[User sharedUser] allItems] count]){
            // 从data source删除数据
            NSArray *items = [[User sharedUser] allItems];
            UserItem *item = items[indexPath.row];
            [[User sharedUser] removeItem:item];
            //删除表格中的对应行 用fade的动画效果(暂时没看出有啥区别...)
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        }
    } else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}

对于删除操作要注意的是,要保证视图和模型对象数据的一致性!

下面这这个方法(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
可以自定义删除的文字

//自定义删除文字
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath{
    if(indexPath.row < [[[User sharedUser] allItems] count]){
        NSArray *items = [[User sharedUser] allItems];
        UserItem *item = items[indexPath.row];
        NSString *del;
        if([item.name isEqualToString:@"xxx"]){
            del = [[NSString alloc]initWithFormat :@"%@,%@", @"再见",  item.name];
        }
        else{
            del = [[NSString alloc]initWithFormat :@"%@,%@", @"滚吧",  item.name];
        }
        return del;
    }
    else
        return @"Unable";
}


移动:

对于移动,使用

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;

注意点依旧是数据模型和试图的一致性

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
    [[User sharedUser] moveItemAtIndex:fromIndexPath.row toIndex:toIndexPath.row];
}

下面这个方法可以对每个cell设置条件的移动,说白了就是让谁移谁不能移

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the item to be re-orderable.
    //设置可以滑动
    NSArray *items = [[User sharedUser] allItems];
    //最后一行不可滑动
    if (indexPath.row + 1 == [items count] + 1) {
        return NO;
    }
    //只有一行数据时也不可滑动
    else if([items count] == 1){
        return NO;
    }
    return YES;
}
还有一个

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath;   

有点复杂,先不说了...



以下是苹果官方的API文档

Configuring a Table View

- tableView:cellForRowAtIndexPath:
Required. 

Asks the data source for a cell to insert in a particular location of the table view.

- numberOfSectionsInTableView:

Asks the data source to return the number of sections in the table view.

- tableView:numberOfRowsInSection:
Required. 

Tells the data source to return the number of rows in a given section of a table view.

- sectionIndexTitlesForTableView:

Asks the data source to return the titles for the sections for a table view.

- tableView:sectionForSectionIndexTitle:atIndex:

Asks the data source to return the index of the section having the given title and section title index.

- tableView:titleForHeaderInSection:

Asks the data source for the title of the header of the specified section of the table view.

- tableView:titleForFooterInSection:

Asks the data source for the title of the footer of the specified section of the table view.


Inserting or Deleting Table Rows

- tableView:commitEditingStyle:forRowAtIndexPath:

Asks the data source to commit the insertion or deletion of a specified row in the receiver.

- tableView:canEditRowAtIndexPath:

Asks the data source to verify that the given row is editable.


Reordering Table Rows

- tableView:canMoveRowAtIndexPath:

Asks the data source whether a given row can be moved to another location in the table view.

- tableView:moveRowAtIndexPath:toIndexPath:

Tells the data source to move a row at a specific location in the table view to another location.





github仓库还没搭好,以后弄好了上传地址吧




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值