我正在尝试选择和编辑新添加对象的名称属性。
在OSX上,我有一个数组控制器,它在表视图中显示其内容。我通过AC的属性连接(使用绑定)了表列的值。此外,我将表视图的内容和selectionIndex绑定设置为指向AC
我的子类AC有一个到表视图的IBOutlet(称为tableView),并且包含来自数据模型的托管对象。
在我的AC中,我覆盖add:方法。
- (void)add:(id)sender {
[super add:sender];
[[self managedObjectContext] processPendingChanges]; // no effect
[tableView reloadData]; // no effect
[tableView scrollRowToVisible:[[self arrangedObjects] count]-1];
}
新添加的对象以选定状态显示在表视图中(我在IB中设置了AC以选择新插入的对象)。但是表视图向下滚动到倒数第二行,将新行置于可见视图之外。
当我尝试这个时,
[tableView scrollRowToVisible:[tableView selectedRow]];
或者这个,
[tableView scrollRowToVisible:[self selectionIndex]];
更糟糕的是:selectionIndex似乎没有正确更新。
- (void)add:(id)sender {
[super add:sender];
NSLog(@"selectionIndex = %lu", [self selectionIndex]);
NSLog(@"number of objects in AC = %lu", [[self arrangedObjects] count]);
}
记录selectionIndex显示它始终显示上一个选择索引。在AC中记录对象的数量总是少了一个。
我是否试图过早地操作表视图?有什么想法更适合推翻哪种方法吗?
关于编辑部分。。
以下语句干扰了上面的scrollRowToVisible:方法,因为最后一个参数似乎也选择了行。
[tableView editColumn:0 row:0 withEvent:nil select:YES];
无论如何,指定的字段(出于测试目的,表的第一行)似乎只是在一瞬间进入编辑模式,但随后立即完成编辑。
如有任何帮助,我们将不胜感激。
我提出的一个解决方案是:
- (void)rearrangeObjects {
[super rearrangeObjects];
[tableView editColumn:0 row:[self selectionIndex] withEvent:nil select:YES];
}
最后一个参数select:YES
不会将表滚动到该行,也不会选择该行。下一行也滚动表格视图。
[tableView editColumn:0 row:[self selectionIndex] withEvent:nil select:NO];
select:YES
选择正在编辑的文本字段中的文本。
尽管如此,我还是想知道我对这件事的看法是否正确。此解决方案要求每个阵列控制器都有一个到显示其数据的表视图的出口。这似乎是多余的,因为表视图(及其列)已经绑定到AC。
试图实现MVC设计模式,难道不应该将编辑单元格的责任委托给表视图吗?
问题是数组控制器没有立即添加新对象。文件-[NArrayController添加:]说:
从Mac OS X v10.4开始,此方法的结果被推迟直到运行循环的下一次迭代,以便错误显示机制(请参阅错误响应程序和错误恢复)可以提供反馈为表单。
我不知道有什么优雅的方法可以绕过这一点。您可以尝试绕过add:
方法,将对象直接添加到数组控制器绑定到的NSMutableArray
中。或者,您可以尝试使用具有短延迟(如0.1秒)的performSelector:withObject:afterDelay:
,此时应该添加对象。