自 iOS 11 起,不会多次滑动 UITableViewCell 触发操作
UITableViewCell won't be swiped to trigger action more than once since iOS 11
自从 Apple 发布 iOS 11 和 trailingSwipeActions
功能后,我的应用程序出现了退化。
我的 TableView
显示消息并允许用户通过向左滑动显示删除按钮来删除消息。
它完美运行,但在 iOS 上运行不佳 11. 滑动操作只能进行一次,然后它对所有行都不再起作用,单元格不会滑动。我在调试控制台中收到以下消息。
*** NSForwarding: warning: method signature and compiler disagree on struct-return-edness of 'prepareWithSwipeDirection:configuration:'.
Signature thinks it does not return a struct, and compiler thinks it
does.
每次都会调用trailingSwipeActionsConfigurationForRowAtIndexPath
方法,但是单元格就是不滑动
我已经尝试实现 iOS 11 中关于此功能的所有新功能,但没有解决我的问题。
还试图弄清楚是否有一些 GestureRecognizer 是随机 "eating" 手势但没有找到任何相关的东西,也很难调试。
下面是我尝试过不同修改后的相关代码:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (BOOL) tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
- (BOOL) tableView:(UITableView *)tableView canFocusRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
return NO;
}
- (BOOL) tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
return NO;
}
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
if (@available(iOS 11.0, *)) {
UIContextualAction * delete = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive title:@"Delete" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
[self deleteMessageAtIndexPath:indexPath];
}];
UISwipeActionsConfiguration *configuration = [UISwipeActionsConfiguration configurationWithActions:@[delete]];
configuration.performsFirstActionWithFullSwipe = false;
return configuration;
}
return nil;
}
- (NSArray<UITableViewRowAction *> *) tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
UITableViewRowAction * delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"Delete" handler:^(UITableViewRowAction * action, NSIndexPath * indexPath){
[self deleteMessageAtIndexPath:indexPath];
}];
return @[delete];
}
- (void) deleteMessageAtIndexPath:(NSIndexPath *)indexPath {
NSString *threadID = [[self.messageArray objectAtIndex:indexPath.row] objectForKey:@"threadID"];
[self.tableView beginUpdates];
[self.messageArray removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
//[self.tableView reloadData];
@weakify(self);
[UIUtil showLoadingHudWithText: @"Deleting..."];
[[AsyncUtil sharedInstance] dispatch_background_network:^{
DBManager *db = [[DBManager alloc] init];
[db deletetableData:[NSString stringWithFormat:@"singleChat WHERE threadID = '%@' ",threadID] ];
[[MemChatThreadMessages sharedInstance] removeThread:threadID];
NSDictionary * result = [Network deleteChatThread:threadID forEmail:[WEUtil getEmail]];
[[AsyncUtil sharedInstance] dispatch_main:^{
[UIUtil hideLoadingHuds];
@strongify(self);
if(self == nil) return ;
if([result[@"result"] isEqualToString:@"success"]){
}else{
//[self.tableView reloadData];
[UIUtil showErrorMessage:@"Cannot delete this thread"];
}
}];
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
感谢您的帮助。
这是由于我的代码中的一个片段引起的 swizzling 造成的:
@implementation NSMutableDictionary (NilSafe)
- (void)gl_setObject:(id)obj forKeyedSubscript:(id<NSCopying>)key {
if (!key) {
return;
}
if (!obj) {
obj = [NSNull null];
}
[self gl_setObject:obj forKeyedSubscript:key];
}
@end
这部分是导致错误的地方:
if (!obj) {
obj = [NSNull null];
}
将 obj = [NSNull null];
更改为 return;
解决了该问题。
原博客post关于问题的解决方法是here(中文)。
自从 Apple 发布 iOS 11 和 trailingSwipeActions
功能后,我的应用程序出现了退化。
我的 TableView
显示消息并允许用户通过向左滑动显示删除按钮来删除消息。
它完美运行,但在 iOS 上运行不佳 11. 滑动操作只能进行一次,然后它对所有行都不再起作用,单元格不会滑动。我在调试控制台中收到以下消息。
*** NSForwarding: warning: method signature and compiler disagree on struct-return-edness of 'prepareWithSwipeDirection:configuration:'. Signature thinks it does not return a struct, and compiler thinks it does.
每次都会调用trailingSwipeActionsConfigurationForRowAtIndexPath
方法,但是单元格就是不滑动
我已经尝试实现 iOS 11 中关于此功能的所有新功能,但没有解决我的问题。
还试图弄清楚是否有一些 GestureRecognizer 是随机 "eating" 手势但没有找到任何相关的东西,也很难调试。
下面是我尝试过不同修改后的相关代码:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (BOOL) tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
- (BOOL) tableView:(UITableView *)tableView canFocusRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
return NO;
}
- (BOOL) tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
return NO;
}
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
if (@available(iOS 11.0, *)) {
UIContextualAction * delete = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive title:@"Delete" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
[self deleteMessageAtIndexPath:indexPath];
}];
UISwipeActionsConfiguration *configuration = [UISwipeActionsConfiguration configurationWithActions:@[delete]];
configuration.performsFirstActionWithFullSwipe = false;
return configuration;
}
return nil;
}
- (NSArray<UITableViewRowAction *> *) tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
UITableViewRowAction * delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"Delete" handler:^(UITableViewRowAction * action, NSIndexPath * indexPath){
[self deleteMessageAtIndexPath:indexPath];
}];
return @[delete];
}
- (void) deleteMessageAtIndexPath:(NSIndexPath *)indexPath {
NSString *threadID = [[self.messageArray objectAtIndex:indexPath.row] objectForKey:@"threadID"];
[self.tableView beginUpdates];
[self.messageArray removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
//[self.tableView reloadData];
@weakify(self);
[UIUtil showLoadingHudWithText: @"Deleting..."];
[[AsyncUtil sharedInstance] dispatch_background_network:^{
DBManager *db = [[DBManager alloc] init];
[db deletetableData:[NSString stringWithFormat:@"singleChat WHERE threadID = '%@' ",threadID] ];
[[MemChatThreadMessages sharedInstance] removeThread:threadID];
NSDictionary * result = [Network deleteChatThread:threadID forEmail:[WEUtil getEmail]];
[[AsyncUtil sharedInstance] dispatch_main:^{
[UIUtil hideLoadingHuds];
@strongify(self);
if(self == nil) return ;
if([result[@"result"] isEqualToString:@"success"]){
}else{
//[self.tableView reloadData];
[UIUtil showErrorMessage:@"Cannot delete this thread"];
}
}];
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
感谢您的帮助。
这是由于我的代码中的一个片段引起的 swizzling 造成的:
@implementation NSMutableDictionary (NilSafe)
- (void)gl_setObject:(id)obj forKeyedSubscript:(id<NSCopying>)key {
if (!key) {
return;
}
if (!obj) {
obj = [NSNull null];
}
[self gl_setObject:obj forKeyedSubscript:key];
}
@end
这部分是导致错误的地方:
if (!obj) {
obj = [NSNull null];
}
将 obj = [NSNull null];
更改为 return;
解决了该问题。
原博客post关于问题的解决方法是here(中文)。