每次删除后,有错误的滑动以删除显示在另一行
Buggy swipe to delete display on one more row after each delete
自 iOS 11 以来,我在 UITableView 删除操作上遇到了一个奇怪的问题。
这是相关的 TableView 代码:
@implementation ChatMessageListViewController(TableView)
#pragma mark - table view datasource/delegate
- (NSArray<UITableViewRowAction *> *) tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
NSMutableArray *rowActions = [NSMutableArray array];
UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"Delete" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
[self deleteMessageAtIndexPath:indexPath];
}];
delete.backgroundColor = [UIColor redColor];
[rowActions addObject:delete];
return [rowActions copy];
}
- (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];
@weakify(self);
[UIUtil showLoadingHudWithText:WELocalString(@"message_remove_thread_loading_text", @"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{
[UIUtil showErrorMessage:WELocalString(@"message_remove_thread_error", @"Cannot delete this thread", @"不能删除该会话!")];
}
[self.tableView reloadData];
}];
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.messageArray count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *messageInfo = [self.messageArray objectAtIndex:indexPath.row];
if ([(NSString *)[messageInfo objectForKey:@"isAnnouncement"] isEqualToString:@"1"]) {
return 80;
}else if ([[messageInfo objectForKey:@"chatTag"] isValidString]){
return 80;
}else if([self isSpecialMessage:messageInfo]){
return 80;
}else{
return 67;
}
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = @"message";
if(self.events == nil){
NSDictionary * d = [WEUtil getMyEventListCache];
self.events = [[NSMutableDictionary alloc] init];
for(NSDictionary * eventSummary in d[@"events"]){
NSString * eventID = eventSummary[@"eventid"];
[self.events setObject:eventSummary forKey:eventID];
}
}
UserMessageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
cell = [[UserMessageTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
if(indexPath.row >= [self.messageArray count]){
TERMINATE_WITH_NIL_CELL;
}
NSDictionary *messageInfo = [self.messageArray objectAtIndex:indexPath.row];
if(![self isSpecialMessage:messageInfo]){
[cell configureCellWithMessageDict:messageInfo];
}else{
[cell configureCellWithNewMessageDict:messageInfo withEvents:self.events];
}
return cell;
}
#pragma mark - Navigation
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSDictionary *msgThreadDict = [self.messageArray objectAtIndex:indexPath.row];
if(![self isSpecialMessage:msgThreadDict]){
[self tableView:tableView didSelectNormalRowAtIndexPath:indexPath];
}else{
NSString * event = msgThreadDict[@"event"];
if([event isValidString]){
if([event isEqualToString:@"no_event_messages"]){
[UIUtil showErrorMessage:@"no event id"];
}else{
[BackendTracking trackingWithAction:@"open_special" withLabel:@"threads_list"];
SpecialTopicListViewController * special = [[SpecialTopicListViewController alloc] init];
special.tracking_src = @"tab";
[self.navigationController pushViewController:special animated:YES];
}
}
}
}
-(void) tableView:(UITableView *)tableView didSelectNormalRowAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *msgThreadDict = [self.messageArray objectAtIndex:indexPath.row];
NSString *threadID = [msgThreadDict objectForKey:@"threadID"];
NSString *jid = [msgThreadDict objectForKey:@"jid"];
[GATracking trackCategory:@"message" withAction:@"thread_list_item_click" withLabel:threadID];
[[MemChatThreadMessages sharedInstance] setCurrentThreadID:threadID];
PrivateMessageViewController * chatVC = [[PrivateMessageViewController alloc] init];
chatVC.threadID = threadID;
chatVC.targetJID = jid;
chatVC.targetName = [msgThreadDict objectForKey:@"name"];
chatVC.unreadMsgNumber = [[self.messageArray objectAtIndex:indexPath.row][@"unreadCnt"] integerValue];
if ([(NSString *)[msgThreadDict objectForKey:@"isGroup"] isEqualToString:@"1"]) {
chatVC.isGroup = YES;
}else{
chatVC.isGroup = NO;
}
chatVC.src = @"list";
WELogInfo(@"click message");
[self.navigationController pushViewController:chatVC animated:YES];
}
@end
随着更新和使用这些尾随滑动操作的更改,每次我删除条目之前都会附加另一个视图(直到它不再起作用)。我试过禁用完整路径或实施 iOS 11 trailingSwipeActionsConfigurationForRowAtIndexPath
但到目前为止我无法解决此问题。
你看到代码有什么问题了吗?主控制器代码在另一个文件中。
删除后尝试重新加载,在这一行之后
[self.tableView 结束更新];
我认为您从 messageArray 中删除了数据,但是因为您没有在那之后重新加载所以 table 视图计数仍然是 2 并且您正在块内重新加载这可能需要时间。
还有一件事你已经从 messageArray 中删除数据,然后从数据库中删除,所以如果你无法从数据库中删除它,你将显示它没有被删除,但对于用户来说它将被删除,因为它不再在消息数组
自 iOS 11 以来,我在 UITableView 删除操作上遇到了一个奇怪的问题。
这是相关的 TableView 代码:
@implementation ChatMessageListViewController(TableView)
#pragma mark - table view datasource/delegate
- (NSArray<UITableViewRowAction *> *) tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
NSMutableArray *rowActions = [NSMutableArray array];
UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"Delete" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
[self deleteMessageAtIndexPath:indexPath];
}];
delete.backgroundColor = [UIColor redColor];
[rowActions addObject:delete];
return [rowActions copy];
}
- (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];
@weakify(self);
[UIUtil showLoadingHudWithText:WELocalString(@"message_remove_thread_loading_text", @"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{
[UIUtil showErrorMessage:WELocalString(@"message_remove_thread_error", @"Cannot delete this thread", @"不能删除该会话!")];
}
[self.tableView reloadData];
}];
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.messageArray count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *messageInfo = [self.messageArray objectAtIndex:indexPath.row];
if ([(NSString *)[messageInfo objectForKey:@"isAnnouncement"] isEqualToString:@"1"]) {
return 80;
}else if ([[messageInfo objectForKey:@"chatTag"] isValidString]){
return 80;
}else if([self isSpecialMessage:messageInfo]){
return 80;
}else{
return 67;
}
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = @"message";
if(self.events == nil){
NSDictionary * d = [WEUtil getMyEventListCache];
self.events = [[NSMutableDictionary alloc] init];
for(NSDictionary * eventSummary in d[@"events"]){
NSString * eventID = eventSummary[@"eventid"];
[self.events setObject:eventSummary forKey:eventID];
}
}
UserMessageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
cell = [[UserMessageTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
if(indexPath.row >= [self.messageArray count]){
TERMINATE_WITH_NIL_CELL;
}
NSDictionary *messageInfo = [self.messageArray objectAtIndex:indexPath.row];
if(![self isSpecialMessage:messageInfo]){
[cell configureCellWithMessageDict:messageInfo];
}else{
[cell configureCellWithNewMessageDict:messageInfo withEvents:self.events];
}
return cell;
}
#pragma mark - Navigation
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSDictionary *msgThreadDict = [self.messageArray objectAtIndex:indexPath.row];
if(![self isSpecialMessage:msgThreadDict]){
[self tableView:tableView didSelectNormalRowAtIndexPath:indexPath];
}else{
NSString * event = msgThreadDict[@"event"];
if([event isValidString]){
if([event isEqualToString:@"no_event_messages"]){
[UIUtil showErrorMessage:@"no event id"];
}else{
[BackendTracking trackingWithAction:@"open_special" withLabel:@"threads_list"];
SpecialTopicListViewController * special = [[SpecialTopicListViewController alloc] init];
special.tracking_src = @"tab";
[self.navigationController pushViewController:special animated:YES];
}
}
}
}
-(void) tableView:(UITableView *)tableView didSelectNormalRowAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *msgThreadDict = [self.messageArray objectAtIndex:indexPath.row];
NSString *threadID = [msgThreadDict objectForKey:@"threadID"];
NSString *jid = [msgThreadDict objectForKey:@"jid"];
[GATracking trackCategory:@"message" withAction:@"thread_list_item_click" withLabel:threadID];
[[MemChatThreadMessages sharedInstance] setCurrentThreadID:threadID];
PrivateMessageViewController * chatVC = [[PrivateMessageViewController alloc] init];
chatVC.threadID = threadID;
chatVC.targetJID = jid;
chatVC.targetName = [msgThreadDict objectForKey:@"name"];
chatVC.unreadMsgNumber = [[self.messageArray objectAtIndex:indexPath.row][@"unreadCnt"] integerValue];
if ([(NSString *)[msgThreadDict objectForKey:@"isGroup"] isEqualToString:@"1"]) {
chatVC.isGroup = YES;
}else{
chatVC.isGroup = NO;
}
chatVC.src = @"list";
WELogInfo(@"click message");
[self.navigationController pushViewController:chatVC animated:YES];
}
@end
随着更新和使用这些尾随滑动操作的更改,每次我删除条目之前都会附加另一个视图(直到它不再起作用)。我试过禁用完整路径或实施 iOS 11 trailingSwipeActionsConfigurationForRowAtIndexPath
但到目前为止我无法解决此问题。
你看到代码有什么问题了吗?主控制器代码在另一个文件中。
删除后尝试重新加载,在这一行之后 [self.tableView 结束更新]; 我认为您从 messageArray 中删除了数据,但是因为您没有在那之后重新加载所以 table 视图计数仍然是 2 并且您正在块内重新加载这可能需要时间。
还有一件事你已经从 messageArray 中删除数据,然后从数据库中删除,所以如果你无法从数据库中删除它,你将显示它没有被删除,但对于用户来说它将被删除,因为它不再在消息数组