iOS 关于UITableView的黑科技

  UITableView是咱们最经常使用的控件了,今天我就来介绍一些关于UITableView的黑科技和一些注意的地方。c++

1.修改左滑删除按钮的高度

  左滑删除这是iOS最早发明的,以后安卓开始模仿。有时候咱们须要对他进行自定义,好比添加图片啊,修改字体和大小啊,其实这个能够很简单。布局

- (void)layoutSubviews {
    
    [super layoutSubviews];
    
    for (UIView *subview in self.subviews) {
        if ([subview isKindOfClass:NSClassFromString(@"UITableViewCellDeleteConfirmationView")]) {
            // 修改左滑删除按钮的高度
            CGRect frame = subview.frame;
            frame.size.height = self.frame.size.height - 10;
            subview.frame = frame;
            
            for (UIButton*deleteBtn in subview.subviews) {
                
                if ([deleteBtn isKindOfClass:[UIButton class]]) {
                    
                    // deleteBtn 就是那个删除按钮 在这里自定义按钮的字体、背景色、添加图片等
                    [deleteBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
                }
            }
            
            break;
        }
    }
}

  UITableViewCellDeleteConfirmationView就是删除按钮所在的View。我此次的需求以下图:字体

调整deleteBtn高度.png
因为删除按钮的高度和cell的高度是一致的,因此会出现左面的效果。不过用户看起来就会很别扭,由于用户理解的cell是不包括灰条的,因此咱们就须要修改删除按钮的高度,其实也就是修改UITableViewCellDeleteConfirmationView的高度。同时,咱们也能够自定义按钮的样式,例如背景色,字体,添加图片等。
  可是我发现这样自定义删除按钮以后,删除起来很是卡顿,由于每次cell布局都须要执行一次for循环,影响效率。因此我强烈建议用下来的方法。动画

- (void)willTransitionToState:(UITableViewCellStateMask)state {
    
    [super willTransitionToState:state];
    if (state == UITableViewCellStateShowingDeleteConfirmationMask) {

        for (UIView *subview in self.subviews) {
        if ([subview isKindOfClass:NSClassFromString(@"UITableViewCellDeleteConfirmationView")]) {
            // 修改左滑删除按钮的高度
            CGRect frame = subview.frame;
            frame.size.height = self.frame.size.height - 10;
            subview.frame = frame;
            
            for (UIButton*deleteBtn in subview.subviews) {
                
                if ([deleteBtn isKindOfClass:[UIButton class]]) {
                    
                    // deleteBtn 就是那个删除按钮 在这里自定义按钮的字体、背景色、添加图片等
                    [deleteBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
                }
            }
            
            break;
        }
    }
  }
}

  不过遍历UITableViewCellDeleteConfirmationView必须延时执行,由于UITableViewCellDeleteConfirmationView是懒加载的,不延时执行,遍历不到UITableViewCellDeleteConfirmationView。code

2.删除cell以后刷新表格

  删除cell以后须要刷新表格,之前我都是用- (void)reloadData;,可是若是表格里的cell不少,频繁的删除,手机就卡死了。由于咱们只是删除一行,却须要刷新整个表格,太浪费资源了。我就想有没有可能像只刷新一行、一段那样的方法呢,后来我发现了下面的方法,很是好。orm

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

他的用法和刷新一行一段彻底同样,可是animation这个参数应该是无效的,由于你不管怎么改动画都没有改变。blog

[self.tableView beginUpdates];
    [self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
    [self.tableView endUpdates];

注意:1.必定要在删除数据源以后,在执行上面的方法。不然会崩溃,报下面的错误:图片

*** Assertion failure in -[ShopCarTableView _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-3318.16.21/UITableView.m:1582
libc++abi.dylib: terminate_handler unexpectedly threw an exception

2.[self.tableView beginUpdates];[self.tableView endUpdates];两句代码能够省略,分别表示开始更新和结束更新,这个更新包括insert、delete、move、reload。
3.用这个方法容易报下面的错误。资源

attempt to delete row 4 from section 0 which only contains 4 rows before the update

这是友盟返回的错误,我定位到错误的位置,反复的删除cell,也没有闪退。我就百思不得其解,上网百度也没有发现有价值的信息。后来我发现:假设一个表格有5行,每行的index分别是0,1,2,3,4。若是我删除了第四行,每行的index就应该变为0,1,2,3,也就是说原来的第五行变成了第四行,index应该是3,但用于没有刷新整个表格,他的index仍然是4,我按照index = 4来刷新这个cell就报上面的错误。是否是有点复杂,没懂。简单一句话,执行了deleteRowsAtIndexPaths方法,表里的每一个cell的indexPath都应该发生变化,可是没有 。其实不是每一个,应该是删除那个cell下面的cell会有变化,便于理解因此说每一个。
  这就尴尬了,是否是又得刷新整个表格了。固然不是了,可是咱们不能直接用cell的indexPath刷新它了。每一个cell都有一个数据,根据这个数据在整个数据源中的位置来从新获取它的indexPath,刷新cell。animation

GoodsModel *goods = notification.object[@"goods"];
    NSUInteger index = [self.tableView.shopCarArr indexOfObject:goods];
    [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:UITableViewRowAnimationNone];

  好司机,都是用汽油堆起来的!说的真对,作的项目多了,遇到的问题也就多,迫使咱们去解决问题,阅读苹果的API。官网API写的真的很详细,也很易懂,不须要有多高的英语造诣,对提升本身真的颇有帮助。另外,这几天的一句经验之谈,任何一个小问题,都不能放过,赶忙解决,不然有可能会酿成大错。

相关文章
相关标签/搜索