ios 动画在 UITableVIew 中插入新部分
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9482072/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Animate the insertion of a new section in UITableVIew
提问by Cosmin
I have this button on my view, and when I press it I insert a new section in my table view ( I have a logical condition in my
我的视图上有这个按钮,当我按下它时,我会在我的表格视图中插入一个新部分(我的表格中有一个逻辑条件
-(NSInteger) numberOfSectionsInTableView:(UITableView*)tableView
{
if (slide==TRUE) return 2;
return 1;
}
And also in my -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath. My section is added as it should, but I have read somewhere that this can be animated, because when I press my button the section is added but with no animation. I think I should use this -(void)insertSections:(NSIndexSet*)sections withRowanimation(UITableViewRowAnimation) animationbut I haven't found a proper example on the web.
而且在我的-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath. 我的部分已按原样添加,但我在某处读到可以设置动画,因为当我按下按钮时,该部分已添加但没有动画。我想我应该使用它,-(void)insertSections:(NSIndexSet*)sections withRowanimation(UITableViewRowAnimation) animation但我还没有在网上找到合适的例子。
回答by Sam
Manipulating rows and sections into UITableView using animation is made pretty easy using the following API's (emphasis on the last two):
使用以下 API 可以很容易地使用动画将行和部分操作到 UITableView 中(重点是最后两个):
insertRowsAtIndexPaths:withRowAnimation:insertSections:withRowAnimation:deleteRowsAtIndexPaths:withRowAnimation:deleteSections:withRowAnimation:beginUpdatesendUpdates
insertRowsAtIndexPaths:withRowAnimation:insertSections:withRowAnimation:deleteRowsAtIndexPaths:withRowAnimation:deleteSections:withRowAnimation:beginUpdatesendUpdates
Updating the Data Model
更新数据模型
You should update your data model anywhere between the beginUpdatesand endUpdatesmethods. It doesn't matter if you update your data model before or after insertion or deletion methods just so long as you do it between the beginUpdatesand endUpdatesmethods.
您应该在beginUpdates和endUpdates方法之间的任何地方更新您的数据模型。在插入或删除方法之前或之后更新数据模型并不重要,只要在beginUpdates和endUpdates方法之间进行即可。
Do not Insert Rows for New Sections You are Inserting
不要为要插入的新节插入行
When adding a new section using the insertSections:withRowAnimation:method, you do not need to call insertRowsAtIndexPaths:withRowAnimation:to add rows into it. The insertRowsAtIndexPaths:withRowAnimation:method is just for animating an existing section changing. Similarly, you do not need to call deleteRowsAtIndexPaths:withRowAnimation:when you remove a section using deleteSections:withRowAnimation:.
使用该insertSections:withRowAnimation:方法添加新部分时,无需调用insertRowsAtIndexPaths:withRowAnimation:向其中添加行。该insertRowsAtIndexPaths:withRowAnimation:方法仅用于为现有部分更改设置动画。同样,deleteRowsAtIndexPaths:withRowAnimation:当您使用 删除部分时不需要调用deleteSections:withRowAnimation:。
Regarding Deleting and Inserting:
关于删除和插入:
I generally do these in separate beginUpdates:endUpdatescalls, however you can insert and delete at the same time. Just be aware that the UITableView will firsttry to delete rows / sections and thentry to insert them regardless of the order you do it in your code.
我通常在单独的调用中执行这些操作,但是您可以同时插入和删除。请注意 UITableView 将首先尝试删除行/节,然后尝试插入它们,而不管您在代码中的执行顺序如何。beginUpdates:endUpdates
Discussionpart of deleteRowsAtIndexPaths:withRowAnimation:
讨论部分deleteRowsAtIndexPaths:withRowAnimation:
Note the behavior of this method when it is called in an animation block defined by the beginUpdates and endUpdates methods. UITableView defers any insertions of rows or sections until after it has handled the deletions of rows or sections. This happens regardless of ordering of the insertion and deletion method calls. This is unlike inserting or removing an item in a mutable array, where the operation can affect the array index used for the successive insertion or removal operation. For more on this subject, see “Batch Insertion and Deletion of Rows and Sections” in Table View Programming Guide for iOS.
请注意在由 beginUpdates 和 endUpdates 方法定义的动画块中调用此方法时的行为。UITableView 将任何行或节的插入推迟到它处理完行或节的删除之后。无论插入和删除方法调用的顺序如何,都会发生这种情况。这与在可变数组中插入或删除项目不同,在可变数组中,该操作会影响用于连续插入或删除操作的数组索引。有关此主题的更多信息,请参阅 iOS 表视图编程指南中的“行和节的批量插入和删除”。
Example of inserting into a section:
插入部分的示例:
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];
回答by QED
UITableViewRowAnimationis an enum declared at the top of UITableView.h You can also view it in the UITableView reference. It's smallish, so I'll just paste it!
UITableViewRowAnimation是在 UITableView.h 顶部声明的枚举,您也可以在UITableView 参考中查看。太小了,我就贴吧!
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;
Basically it tells the table view from which direction you want the rows/sections to be animated in/out. A little experimenting will demonstrate the effect of each.
基本上它告诉表格视图您希望行/部分从哪个方向进入/退出动画。一些实验将证明每个的效果。
For example, inserting a row with UITableViewRowAnimationTopwill trigger an animation which gives the impression of a row coming into the table view from a space immediately above that of its final destination in the table view.
例如,插入一行UITableViewRowAnimationTop将触发一个动画,该动画给人的印象是一行从表视图中其最终目标位置正上方的空间进入表视图。
So your insertion might look like:
所以你的插入可能看起来像:
-(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];
}
And you will have to be sure that your delegate and data source provide info that is consistent with your assertion to insert sections/rows. From your question, it looks like you have done so.
并且您必须确保您的委托和数据源提供与您插入节/行的断言一致的信息。从您的问题来看,您似乎已经这样做了。
EDITS:
编辑:
I don't thinkyou have to call reloadData. UITableViewrequires that your data model reflect the changes you make with with the insert/delete methods. So that, for example, if, before a call to insertSections:withRowAnimation:(with which you are inserting a single section), your numberOfSectionsInTableView:method returned 1, then, after the call, it mustreturn 2. To do otherwise throws an exception. It is this enforcement of consistency that allows you (again, I think) to avoid the call to reloadData- the necessary data is being reloaded by the whole beginUpdates:endUpdates:transaction, and any updates to the model you make during that transaction must match one-for-one your insert/delete calls.
我认为你不必打电话给reloadData。UITableView要求您的数据模型反映您使用插入/删除方法所做的更改。因此,例如,如果在调用insertSections:withRowAnimation:(通过它插入单个部分)之前,您的numberOfSectionsInTableView:方法返回 1,那么在调用之后,它必须返回 2。否则会引发异常。正是这种一致性的实施使您(我再次认为)避免调用reloadData- 整个beginUpdates:endUpdates:事务正在重新加载必要的数据,并且您在该事务期间对模型进行的任何更新都必须一对一匹配您的插入/删除电话。
Clear as mud?
清如泥?
UPDATES
更新
If you were programming explicit animations, then I would say that you could do it in the 'completion handler' (or just program the animation directly for that matter), but that is not available to you here. I think you can wrap the button-presenting code in its own method in the view, then set a timer to call it after a short amount of time, say, .2 seconds (you'll have to experiment to see what looks good). e.g.
如果您正在编写显式动画,那么我会说您可以在“完成处理程序”中执行此操作(或者直接为此编写动画),但这对您来说不可用。我认为您可以将按钮呈现代码包装在视图中自己的方法中,然后设置一个计时器在很短的时间后调用它,例如 0.2 秒(您必须尝试看看什么看起来不错) . 例如
[NSTimer scheduledTimerWithTimeInterval:.2 target:self selector:@selector(presentButton) userInfo:nil repeats:NO];
That should do the trick.
这应该够了吧。
回答by Roshit
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
This method pointed out by will definitely do the magic.
所指出的这种方法肯定会发挥作用。
Probably you can try this:
也许你可以试试这个:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
Writing straight out of my mind.. hope this helps...
直接写出我的想法..希望这会有所帮助......
Please note:
请注意:
- Any of the
UITableViewRowAnimationcan be used. sectionIndexin the mentioned code is an NSInteger. Probably in your case 1.
UITableViewRowAnimation可以使用任何一个。sectionIndex在提到的代码中是一个 NSInteger。可能在你的情况下 1。

