【问题标题】:Animate the insertion of a new section in UITableVIew在 UITableVIew 中插入新部分的动画
【发布时间】:2016-09-15 19:37:09
【问题描述】:

我的视图上有这个按钮,当我按下它时,我会在我的表格视图中插入一个新部分(我的

-(NSInteger) numberOfSectionsInTableView:(UITableView*)tableView
{
    if (slide==TRUE) return 2;
    return 1;
}

还有我的-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath。我的部分按应有的方式添加,但我在某处读到这可以动画,因为当我按下按钮时,该部分被添加但没有动画。我想我应该使用这个-(void)insertSections:(NSIndexSet*)sections withRowanimation(UITableViewRowAnimation) animation,但我在网上没有找到合适的例子。

【问题讨论】:

    标签: ios uitableview animation


    【解决方案1】:

    使用以下 API 可以很容易地使用动画将行和部分操作到 UITableView 中(强调最后两个):

    更新数据模型

    您应该在 beginUpdatesendUpdates 方法之间的任意位置更新您的数据模型。只要在 beginUpdatesendUpdates 方法之间进行,在插入或删除方法之前或之后更新数据模型都没有关系。

    不要为要插入的新部分插入行

    使用insertSections:withRowAnimation: 方法添加新部分时,您无需调用insertRowsAtIndexPaths:withRowAnimation: 来向其中添加行。 insertRowsAtIndexPaths:withRowAnimation: 方法仅用于为现有部分更改动画。同样,当您删除使用deleteSections:withRowAnimation: 的部分时,您不需要调用deleteRowsAtIndexPaths:withRowAnimation:

    关于删除和插入:

    我通常在单独的 beginUpdates: endUpdates 调用中执行这些操作,但是您可以同时插入和删除。请注意,UITableView 将首先尝试删除行/部分,然后然后尝试插入它们无论您在代码中执行的顺序如何.

    讨论部分deleteRowsAtIndexPaths:withRowAnimation:

    注意在动画中调用此方法时的行为 由 beginUpdates 和 endUpdates 方法定义的块。 UITableView 将任何行或节的插入推迟到处理完之后 行或节的删除。无论订购如何,都会发生这种情况 插入和删除方法调用。这与插入不同 或删除可变数组中的项目,该操作可能会影响 用于连续插入或删除的数组索引 手术。有关此主题的更多信息,请参阅“批量插入和删除 iOS 的 Table View Programming Guide 中的“行和节”。

    插入节的示例:

    int indexOfNewSection = 4; // TODO: change to meaningful value
    [self.tableview beginUpdates];
    [self.tableview insertSections:[NSIndexSet indexSetWithIndex:indexOfNewSection]
                  withRowAnimation:UITableViewRowAnimationAutomatic];
    
    // Update data model
    [self.sections insertObject:sectionObj atIndex:indexOfNewSection];
    
    [self.tableview endUpdates];
    

    【讨论】:

    • 另外,在对行和节的插入/删除进行动画处理时,不需要调用UITableViewreloadData 方法。调用reload data 将重新加载视图中的所有单元格和行(没有动画)。此外,我的示例来自工作代码,修改很少。
    • 非常感谢,它运行良好。我还有一个问题,有什么方法可以在动画完成后调用方法?
    • @Cosmin 不幸的是,我不知道任何UITableView 动画更改事件的任何回调或完成块。您可以在 SO 上将其作为一个新问题打开,以查看其他社区成员是否知道如何做到这一点。
    • 引用您的帖子。我可以问一个与添加部分相关的问题吗?
    【解决方案2】:

    UITableViewRowAnimation 是在 UITableView.h 顶部声明的枚举,您也可以在UITableView reference 中查看。太小了,我就贴吧!

    typedef enum {
        UITableViewRowAnimationFade,
        UITableViewRowAnimationRight,           // slide in from right (or out to right)
        UITableViewRowAnimationLeft,
        UITableViewRowAnimationTop,
        UITableViewRowAnimationBottom,
        UITableViewRowAnimationNone,            // available in iOS 3.0
        UITableViewRowAnimationMiddle,          // available in iOS 3.2.  attempts to keep cell centered in the space it will/did occupy
        UITableViewRowAnimationAutomatic = 100  // available in iOS 5.0.  chooses an appropriate animation style for you
    } UITableViewRowAnimation;
    

    基本上,它告诉表格视图您希望行/部分从哪个方向进/出动画。稍作实验即可证明每种方法的效果。

    例如,插入带有UITableViewRowAnimationTop 的行将触发动画,给人的印象是一行从表格视图中其最终目标位置上方的空间进入表格视图。

    所以你的插入可能看起来像:

    -(void)sliderValueChanged:(id)slider {
       slide = slider.on;
    
       [tableView beginUpdates];
    
       if (slider.on) {
          [tableView insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationTop];
          // TODO: update data model by inserting new section
       } else {
          [tableView deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationTop];
          // TODO: update data model by removing approprite section
       }
    
       [tableView endUpdates];
    }
    

    并且您必须确保您的委托和数据源提供的信息与您插入部分/行的断言一致。从您的问题来看,您似乎已经这样做了。

    编辑:

    我不认为你必须打电话给reloadDataUITableView 要求您的数据模型反映您使用插入/删除方法所做的更改。因此,例如,如果在调用 insertSections:withRowAnimation:(使用它插入单个部分)之前,您的 numberOfSectionsInTableView: 方法返回 1,那么在调用之后,它必须返回2. 否则会引发异常。正是这种一致性的强制执行使您(再次,我认为)避免调用 reloadData - 整个 beginUpdates: endUpdates: 事务正在重新加载必要的数据,以及任何您在该事务期间对模型所做的更新必须与您的插入/删除调用一对一匹配。

    一清二楚?

    更新

    如果您正在编写显式动画,那么我会说您可以在“完成处理程序”中进行(或者直接对动画进行编程),但在这里您无法使用。我认为您可以在视图中将按钮呈现代码包装在其自己的方法中,然后设置一个计时器以在短时间内调用它,例如 0.2 秒(您必须尝试看看什么看起来不错) .例如

    [NSTimer scheduledTimerWithTimeInterval:.2 target:self selector:@selector(presentButton) userInfo:nil repeats:NO];
    

    这应该可以解决问题。

    【讨论】:

    • 不幸的是我现在不在我的 Mac 上,所以我无法测试它,但这对我来说似乎很清楚,我坚信它会起作用。另外,如果我打电话给insertSections,我还需要打电话给reloadData吗?
    • 是的,这很清楚。在我测试这个之后,我会告诉你它是怎么回事。感谢您的帮助,您的回答非常好。
    • 此代码缺少对UITableViewbeginUpdatesendUpdates 方法的调用,因此它不起作用。此外,在beginUpdatesendUpdates 调用之间的某个位置更新数据模型也很重要。最后,如果您调用reloadData,则没有必要做动画,因​​为这将重新加载所有数据并根据新表格数据重新渲染任何可见的表格视图单元格。所以,如果你想要动画,不要打电话给reloadData
    • 已编辑。感谢您对 reloadData: 的信任,我对此不确定。
    • 工作得很好,非常感谢。我还有一个问题,无论如何我可以在动画结束后调用一个方法吗?我想在视图上添加一个按钮,但它会在动画运行时添加它。
    【解决方案3】:
    - (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
    

    所指出的这种方法肯定会变魔术。

    或许你可以试试这个:

    [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
    

    直接写在我的脑海里..希望这会有所帮助......

    请注意:

    1. 可以使用任何UITableViewRowAnimation
    2. 上述代码中的sectionIndex 是一个NSInteger。可能是您的情况 1。

    【讨论】:

    • 引用您的帖子。我可以问一个与添加部分有关的问题吗?
    猜你喜欢
    • 1970-01-01
    • 2012-06-14
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    • 2015-03-03
    • 1970-01-01
    • 2011-08-02
    相关资源
    最近更新 更多