延迟commitEditingStyle中的模型和表视图更改

编程入门 行业动态 更新时间:2024-10-11 15:22:46
本文介绍了延迟commitEditingStyle中的模型和表视图更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

是否必须直接从 commitEditingStyle 开始模型更改和行动画,或者可以在以后的运行循环迭代中完成?

Does the model change and the row animation have to be started directly from commitEditingStyle or can it be done in a later run loop iteration?

我问是因为它似乎可以在iOS 10上运行,但是在iOS 11上它至少会破坏删除动画.这仅仅是iOS 11中的错误,还是总的来说是个坏主意?

I am asking because it appears to work on iOS 10, but on iOS 11 it breaks at least the delete animation. Is it simply a bug in iOS 11 or is it a bad idea in general?

是否有更好的方法来触发异步删除操作并在完成时为表视图更改设置动画? 第一张照片显示了它在iOS 11上的损坏方式(删除"按钮与下一个单元格重叠).第二张图片显示了在iOS 10上的效果.

Is there a better way to trigger an asynchronous delete operation and animate the table view change on completion? The first picture shows how it breaks on iOS 11 (The delete button overlaps the next cell). The second picture shows how it looks fine on iOS 10.

这是有趣的片段:

This is the interesting snipped:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { dispatch_async(dispatch_get_main_queue(), ^{ [_model removeObjectAtIndex:indexPath.row]; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; }); } }

如果我删除 dispatch_async(... ,它可以在iOS 10和11上正常运行.第一张图片显示了iOS 11,第二张显示了iOS 10.

If I remove the dispatch_async(..., it works as expected on iOS 10 and 11. The first picture shows iOS 11, the second iOS 10.

这是用于测试它的表视图控制器的完整代码:

Here is the full code of the table view controller used to test it:

#import "TableViewController.h" @implementation TableViewController { NSMutableArray<NSString *>* _model; } - (void)viewDidLoad { [super viewDidLoad]; _model = [[NSMutableArray alloc] init]; [self.tableView registerClass:UITableViewCell.class forCellReuseIdentifier:@"cell"]; for (NSInteger i = 0; i < 200; i++) { [_model addObject:[NSString stringWithFormat:@"Test Row %ld Test Test Test Test Test", (long)i]]; } } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return _model.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath]; cell.textLabel.text = _model[indexPath.row]; return cell; } - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { return YES; } - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { dispatch_async(dispatch_get_main_queue(), ^{ [_model removeObjectAtIndex:indexPath.row]; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; }); } } @end

更新:将此方法添加到表视图控制器后,iOS 11对其进行了修复,并允许延迟模型更改和行动画.(感谢ChrisHaze)

Update: Adding this method to the table view controller fixes it for iOS 11 and allows delaying the model change and row animation. (Thanks to ChrisHaze)

- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(11_0) { UIContextualAction* deleteAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive title:@"Delete" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) { dispatch_async(dispatch_get_main_queue(), ^{ [_model removeObjectAtIndex:indexPath.row]; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; completionHandler(YES); }); }]; UISwipeActionsConfiguration* config = [UISwipeActionsConfiguration configurationWithActions:@[deleteAction]]; return config; }

推荐答案

似乎对iOS 11中的UITableview进行了更改.

It seems that there have been changes made to the UITableview in iOS 11.

Apple的Build发行说明:

Apple's Build release notes :

"删除滑动动作的行为已更改.实现commitEditingStyle:来删除滑动行时,请在数据源中删除该行,然后在表视图上调用deleteRowsAtIndexPaths:以显示滑动删除动画."

经过进一步研究,我发现您必须先调用 beginUpdates ,然后再调用 deleteRowAtIndexPath:方法,以及之后的 endUpdates 方法

After further research, I found that you must call the beginUpdates prior to calling the deleteRowAtIndexPath: method, along with the endUpdates method after.

根据Apple的文档,不调用这些tableView方法将导致潜在的数据模型问题并影响删除动画.

According to Apple's documentation, not calling these tableView methods will result in potential data model issues and effect the deletion animations.

话虽如此,这里有一个答案,其中包括对Apple开发人员论坛上的一个问题,该问题解决了一个非常相似的问题.

With that said, there is an answer that includes the required code to a question on the Apple dev forums that addresses a very similar question.

回答您的实际问题:

  • 需要在开始进行UI更改的beginUpdates和endUpdates块之前调用模型更改.
  • 更新UITableView将减轻同步/动画问题.

---------------------------- 其他详细信息 ----------------------------

---------------------------- additional details ----------------------------

研究完您的评论中的详细信息之后,我提供了一个链接(以上),该链接是Apple提供的最新《表视图编程指南》.您或其他有此问题的人将进入指南的部分,其中包括您添加到问题中的详细信息.

After looking into the details within your comment, I've included a link (above) that is the latest Table View Programming Guide provided by Apple. It will take you, or anyone else with this issue, to the section of the guide that includes the details you've added to your question.

还有一个方便的注释,其中包括如何在必要的情况下从 commitEditingStyle 方法中进行 deleteRowAtIndexPath 调用.

There is also a handy note that includes how to make the deleteRowAtIndexPath call from within the commitEditingStyle method if one must.

更多推荐

延迟commitEditingStyle中的模型和表视图更改

本文发布于:2023-10-18 15:14:26,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1504603.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:视图   模型   commitEditingStyle

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!