UITableView数据更新问题

简介:
  • 自身遇到问题
  • 拓展-进行增删数据时的注意点

    • beginUpdates方法和endUpdates方法是什么呢?
    • 一般什么时候使用这么一个动画块呢?

      • 插入指定的行
      • 插入分组到制定位置
      • 删除制定位置的分组
      • 移动分组
  • 问答区

自身遇到问题

今天在设计自定义UITableViewCell的时候遇到一个愚蠢的问题,就是当用户在Cell上面使用自定义按钮触发删除时,为了保证删除时有动画效果,所以不能在执行deleteRowsAtIndexPaths: withRowAnimation:之后手动执行reloadData
这样就有一个问题,由于不执行reloadData,我们需要获取到Cell最新的indexPath就遇到问题

解决方案:
通过获取按钮所在的Cell的indexPath解决

方式一:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    AMDeleteCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];

    [cell setDeleteBlock:^(NSDictionary *dic, AMDeleteCell *cell) {
  
        //UITableViewCellContentView
        UIView *v = [sender superview];
    
        //UITableViewCell
        UITableViewCell *cell = (UITableViewCell*)[v superview];
        NSIndexPath *indexPath = [tableView indexPathForCell:cell];
        self.deleteIndexPath = indexPath;

    }];

    return cell;

}

方式二(个人认为比较好的一种方式):

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    AMDeleteCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];

    [cell setDeleteBlock:^(NSDictionary *dic, AMDeleteCell *cell) {

        NSIndexPath *indexPath = [tableView indexPathForCell:cell];

        self.deleteIndexPath = indexPath;

    }];

    return cell;

}

自定义Cell内部部分代码:


#import "AMDeleteCell.h"

typedef void(^DeleteCellBlock)(NSDictionary *dic, AMDeleteCell *cell);

@interface AMDeleteCell ()

@property (strong, nonatomic) UIButton        *deleteBtn;
@property (strong, nonatomic) NSDictionary    *dataDic;
@property (copy, nonatomic  ) DeleteCellBlock block;

@end

@implementation AMDeleteCell

//…省略部分代码...

- (void)setDeleteBlock:(void (^)(NSDictionary *, AMDeleteCell *))block {
    self.block = block;
}

#pragma mark - Cell上面按钮触发的方法

- (void)deleteAction:(UIButton *)sender {
    if (_block) {
        _block(_dataDic, self);
    }
}

//...省略部分代码...

@end

拓展-进行增删数据时的注意点

1、普通形式(UITableViewStylePlain)数据增删

将tableView进行增删时需要先更新数据源,然后再执行delete/insert操作

2、分组形式(UITableViewStyleGrouped)数据增删

如果我们的UITableView是UITableViewStyleGrouped的时候,我们如果删除某个Group的最后一条记录时,相应的分组也将被删除。所以,必须保证UITableView的分组,和Cell同时被删除。所以,就需要使用beginUpdates方法和endUpdates方法,将要做的删除操作“包”起来!

beginUpdates方法和endUpdates方法是什么呢?

  1. 这两个方法,是配合起来使用的,标记了一个tableView的动画块。
  2. 分别代表动画的开始和结束。两者成对出现,可以嵌套使用。
  3. 一般,在添加删除选择tableView中使用,并实现动画效果。
  4. 在动画块内,不建议使用reloadData方法,如果使用,会影响动画

一般什么时候使用这么一个动画块呢?

一般在UITableView执行:删除行插入行删除分组插入分组时使用!用来协调UITableView的动画效果。

插入指定的行

在执行该方法时,会对数据源进行访问(分组数据和行数据),并更新可见行。所以,在调用该方法前,应该先更新数据源

- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths
              withRowAnimation:(UITableViewRowAnimation)animation

插入分组到制定位置

插入一个特定的分组。如果,指定的位置上已经存在了分组,那么原来的分组向后移动一个位置。

- (void)insertSections:(NSIndexSet *)sections
      withRowAnimation:(UITableViewRowAnimation)animation

删除制定位置的分组

删除一个制定位置的分组,其后面的分组向前移动一个位置。

- (void)deleteSections:(NSIndexSet *)sections
      withRowAnimation:(UITableViewRowAnimation)animation

移动分组

移动原来的分组从一个位置移动到一个新的位置。如果,新位置上若存在某个分组,那这某个分组将会向上(下)移动到临近一个位置。该方法,没有动画参数。会直接移动。并且一次只能移动一个分组。

- (void)moveSection:(NSInteger)section
          toSection:(NSInteger)newSection

在如上方法中,建议使用该动画块进行操作!


问答区

  1. 为什么block属性使用copy修饰?
    答:Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的。ARC和非ARC声明都是一样的,当然注意在非ARC下要release Block。

再一次感谢您花费时间阅读这篇文章!

微博: @Danny_吕昌辉
博客: SuperDanny

目录
相关文章
|
3月前
|
开发者 iOS开发
介绍 UITableView 和 UICollectionView,它们的区别是什么?
介绍 UITableView 和 UICollectionView,它们的区别是什么?
58 0
|
Java Android开发 UED
ListView的数据更新问题
notifyDataSetChanged()方法会判断是否需要重新渲染,如果当前item没有必要重新渲染 是不会重新渲染的,如果某个Item的状态发生改变,都会导致View的重绘,而重绘的并不是 所有的Item,而是View状态发生变化的那个Item!所以我们直接notifyDataSetChange()方法 即可,当然知道多一个上面的方法也没什么。
102 0
UITableView的创建
UITableView的创建
75 0
|
iOS开发
iOS UITableViewCell嵌套CollectionView,tableview和collectionview同时滑动bug修复
iOS UITableViewCell嵌套CollectionView,tableview和collectionview同时滑动bug修复
922 0
UIcollectionViewCell(UItableviewcell)长按删除操作
功能简单,陷阱不少: 主要涉及两个功能: 1、长按手势:UILongPressGestureRecognizer 2、cell自带的删除操作:deleteItemsAtIndexPaths 首先为cell添加长按手势: UILongPressGestureRecognizer* longgs=[[UILongPressGestureRecognizer all
1459 0
关于TableView中图片的延时加载
经常我们会用tableView显示很多条目, 有时候需要显示图片, 但是一次从服务器上取来所有图片对用户来浪费流量, 对服务器也是负担.最好是按需加载,即当该用户要浏览该条目时再去加载它的图片。
925 0