iOS 7 beginUpdates endUpdates不一致
编辑 :这个答案的解决scheme是有关iOS7有时返回NSIndexPath
和其他时间返回NSMutableIndexPath
。 这个问题与begin/endUpdates
没有什么关系,但希望解决scheme能够帮助其他人。
所有 – 我在iOS 7上运行我的应用程序,我遇到了UITableView
的beginUpdates
和endUpdates
方法的问题。
我有一个tableview需要改变一个单元格的高度时,触摸。 以下是我的代码:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { // If our cell is selected, return double height if([self cellIsSelected:indexPath]) { return 117; } // Cell isn't selected so return single height return 58; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ ChecklistItemCell *cell = (ChecklistItemCell *)[self.tableview cellForRowAtIndexPath:indexPath]; [cell.decreaseButton setHidden:NO]; [cell.increaseButton setHidden:NO]; // Toggle 'selected' state BOOL isSelected = ![self cellIsSelected:indexPath]; DLog(@"%@", selectedIndexes); DLog(@"is selected: %@", isSelected ? @"yes":@"no"); // Store cell 'selected' state keyed on indexPath NSNumber *selectedIndex = @(isSelected); selectedIndexes[indexPath] = selectedIndex; [tableView beginUpdates]; [tableView endUpdates]; }
beginUpdates
和endUpdates
方法工作相当不一致。 didSelectRowAtIndexPath
方法会在每次触摸时被正确调用(我认为一开始UI被阻塞),而selectedIndexes
正确地存储交替值。 问题是,有时我触摸一个表格单元格,所有的方法都调用正确,但单元格高度不会改变。 任何人都知道发生了什么事?
iOS7中的行为有所变化,其中索引path有时是NSIndexPath
实例,其他时间是UIMutableIndexPath
。 问题是这两个类之间的isEqual
总是返回NO
。 因此,您不能可靠地使用索引path作为字典键或依赖于isEqual
其他情况。
我可以想到几个可行的解决scheme:
-
编写一个总是返回
NSIndexPath
实例并使用它来生成密钥的方法:- (NSIndexPath *)keyForIndexPath:(NSIndexPath *)indexPath { if ([indexPath class] == [NSIndexPath class]) { return indexPath; } return [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section]; }
-
通过数据识别行,而不是索引path。 例如,如果您的数据模型是一个
NSString
数组,则使用该string作为您的selectedIndexes
映射关键字。 如果你的数据模型是一个NSManagedObjects
数组,使用objectID
等
我在我的代码中成功地使用了这两个解决scheme。
编辑修改解决scheme(1)基于@ robbuild议返回NSIndexPaths
而不是NSStrings
。
beginUpdates
之后不应该立即endUpdates
。 后者的文档指出,“开始一系列的方法调用,插入,删除或select接收器的行和部分。 这表明它应该在willSelectRowAtIndexPath:
endUpdates
willSelectRowAtIndexPath:
endUpdates
应该在didSelectRowAtIndexPath
调用。