我试图非常接近地模仿iPhone手机应用程序最近调用TableView的功能,使用OS X上的NSTableView。所需的功能是单击一个按钮,TableView 将从显示所有最近的呼叫切换到显示未接的呼叫的子集,并且,我希望有您在 iPhone 上看到的动画,其中行的外观和消失是动画。
我正在使用基于视图的 NSTableView,并且我在我的视图控制器中通过手动数据源和委托(不使用 cocoa 绑定)非常简单地连接了它。
除了尝试删除行以显示"未接"呼叫的子集外,一切正常。如果我只是重建作为表视图数据源的 NSMutableArray,然后调用 reloadData,它就可以完美地工作。但这没有给我动画。下面是未动画的版本,它使表视图和数据源NSMutableArray完全同步,表视图中的内容正确,但没有动画:
- (IBAction)showMissed:(id)sender {
NSMutableIndexSet *indices = [NSMutableIndexSet indexSet];
Call *call;
for (call in callsArray) {
if (!call.missed) {
[indices addIndex:[callsArray indexOfObject:call]];
}
}
if ([indices count] > 0) {
[callsArray removeObjectsAtIndexes:indices];
[self.recentsTableView reloadData];
}
}
当我尝试使用 NSTableView removeRowsAtIndexes:indices withAnimation:
方法来获取我想要的动画时,我遇到了一些非常奇怪的行为。这是动画显示错过的方法:
- (IBAction)showMissed:(id)sender {
NSMutableIndexSet *indices = [NSMutableIndexSet indexSet];
Call *call;
for (call in callsArray) {
if (!call.missed) {
[indices addIndex:[callsArray indexOfObject:call]];
}
}
if ([indices count] > 0) {
[callsArray removeObjectsAtIndexes:indices];
[self.recentsTableView removeRowsAtIndexes:indices withAnimation:NSTableViewAnimationSlideUp];
}
}
我在该方法的动画版本中使用的逻辑是从Apple的TableViewPlaygound示例代码中提取的。
当我运行这段代码时,我得到两个奇怪的结果。首先,TableView 不仅显示"未接"的调用 - 它显示正确的行数(即 TableView 中的行数等于标记为未接的 Call 对象数),但行中显示的实际对象有些未接,有些没有错过。
更奇怪的是,在动画版本运行后,callsArray 包含所有 Call 对象,就好像 [callsArray removeObjectsAtIndexes:indices];
语句根本不存在一样。似乎removeRowsAtIndexes:indices withAnimation:
方法以某种方式弄乱了我的数据源数组的内容并使整个事情失灵。
FWIW,我的动画 showAll 方法基本上与上述使用insertRowsAtIndexes:indices withAnimation:
相反的方法似乎完美运行。
我做错了什么?
数据源数组和表视图之间的同步中一定存在一些损坏。我通过在方法顶部添加 reloadData 调用来修复它。这是固定的 showMissing 方法:
- (IBAction)showMissed:(id)sender {
NSMutableIndexSet *indices = [NSMutableIndexSet indexSet];
Call *call;
[self.recentsTableView reloadData];
for (call in callsArray) {
if (!call.missed) {
[indices addIndex:[callsArray indexOfObject:call]];
}
}
if ([indices count] > 0) {
[callsArray removeObjectsAtIndexes:indices];
[self.recentsTableView removeRowsAtIndexes:indices withAnimation:NSTableViewAnimationSlideUp];
}
}