美文网首页技术笔记
UITableView deleteRowsAtIndexPat

UITableView deleteRowsAtIndexPat

作者: gqlx_sza | 来源:发表于2017-06-19 20:53 被阅读0次
    • 背景

      需求要实现一个列表中cell被删除的动画效果,UI要求cell之间有 10pt的间隔,所以通过在自定义cell的setFrame方法中修改fram的height 达到了分段的tableView效果。
    image.png
    • 问题

      在调用了deleteRowsAtIndexPaths和reloadRowsAtIndexPaths后, 发现cell的高度被多次修改导致 fram比预计的小了10pt(分段间隔的高度)
    image.png
    • 原因

    先说原因 重载部分cell、删除cell、插入cell的动作是在原来cell的位置用新的cell替换,原cell的height已经调用setFrame,新的cell也会走一遍setFrame,所以最后会发现 可视的所有cell都会出现间隔放大10pt(fram.size.height 小了10pt)

    • 解决方案

    放弃在setframe中修改fram的实现cell分段的间隔效果的方式,而是在contentview中布局实现(添加view类似,不再赘述)。
    缺点:如果cell 有整体的点击效果或者左滑动业务会导致间隔也在操作范围内,尤其是由于点击背景色时。



    重新了解下这几个方法:

      - (void)beginUpdates;
      - (void)endUpdates;
      -  (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
      - (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
      - (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
      - (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation;
      - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation;
      - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
    

    The UITableView class allows you to insert, delete, and reload a group of rows or sections at one time, animating the operations simultaneously in specified ways. The eight methods shown in Listing 7-7 pertain to batch insertion and deletion. Note that you can call these insertion and deletion methods outside of an animation

    文档告诉我们

    UITableView允许您一次插入、删除和重新加载 部分rows或者sections ,同时指定动画的操作方式。上面所示的八个方法适合批量插入和删除。注意,您可以调用这些插入和删除方法之外的一个动画

    demo about Inserting and deleting a block of rows in a table view

    > - (IBAction)insertAndDeleteRows:(id)sender {
        // original rows: Arizona, California, Delaware, New Jersey, Washington
     
        [states removeObjectAtIndex:4]; // Washington
        [states removeObjectAtIndex:2]; // Delaware
        [states insertObject:@"Alaska" atIndex:0];
        [states insertObject:@"Georgia" atIndex:3];
        [states insertObject:@"Virginia" atIndex:5];
     
        NSArray *deleteIndexPaths = [NSArray arrayWithObjects:
                                    [NSIndexPath indexPathForRow:2 inSection:0],
                                    [NSIndexPath indexPathForRow:4 inSection:0],
                                    nil];
        NSArray *insertIndexPaths = [NSArray arrayWithObjects:
                                    [NSIndexPath indexPathForRow:0 inSection:0],
                                    [NSIndexPath indexPathForRow:3 inSection:0],
                                    [NSIndexPath indexPathForRow:5 inSection:0],
                                    nil];
        UITableView *tv = (UITableView *)self.view;
     
        [tv beginUpdates];
        [tv insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationRight];
        [tv deleteRowsAtIndexPaths:deleteIndexPaths withRowAnimation:UITableViewRowAnimationFade];
        [tv endUpdates];
     
        // ending rows: Alaska, Arizona, California, Georgia, New Jersey, Virginia
    }
    

    操作的执行顺序
    在上面的例子中,你肯定注意到 deleteRowsAtIndexPaths:withRowAnimation:方法写在 insertRowsAtIndexPaths:withRowAnimation:之后。然而,这并不是tableView真正的操作顺序。实际上,所有的插入和重载都会在删除动作完成之后才执行

    上面的使用场景是我们经常会用到的,但是大家使用过程中要结合实际场景比如:
    1.如果你的操作是通过cell 的block回调传递indexPath实现的话,就需要考虑前面执行的cell在删除和增加之后 是否需要重新配置后面cell已经拿到的indexPath,否则可能导致数组越界的问题。
    2.如果deleteRowsAtIndexPaths:的row为该section的最后一行(indexPath.row = 0),就需要调用deleteSections:删除整个section。

    总结来说:在执行删除和插入之前,把数据源必须准确完善。数据源操作的个数和cell操作个数必须对应。

    相关文章

      网友评论

        本文标题:UITableView deleteRowsAtIndexPat

        本文链接:https://www.haomeiwen.com/subject/fgjnqxtx.html