我有一个带有 NSOpenPanel
的 accessoryView
;在此 View 中,用户选择几个单选按钮来更改允许的类型。当面板打开时,启用正确的文件,禁用其他文件。好的,很好。
现在用户更改了单选按钮,accessoryView 的 viewController
观察单选按钮矩阵的变化,并因此更改 NSOpenPanel 的 allowedTypes
。
之后,按照 Apple 文档,它调用 -validateVisibleColumns
,但面板中没有任何可见的变化。那就是:正确的文件似乎被禁用了:我可以选择它们,但它们是灰色的!
另一个错误效果:我选择了一个文件(启用),更改文件类型,(现在错误的)文件保持选中状态,启用了确定按钮:但这是错误的文件类型!似乎发生了变化但界面不知道!
我的代码是(选择绑定(bind)到单选按钮矩阵):
- (void)observeValueForKeyPath.....
{
NSString *extension = (self.selected==0) ? @"txt" : @"xml";
[thePanel setAllowedFileTypes:@[extension, [extension uppercaseString]]];
[thePanel validateVisibleColumns];
}
我首先尝试插入调用
[thePanel displayIfNeeded]
然后我试过
[thePanel contentView] setNeedsDisplay]
没有结果。我还尝试实现面板委托(delegate)方法
panel:shouldEnableURL:
,应该由 validateVisibleColumns
调用:我刚刚发现它在 NSOpenPanel 的打开时只被调用了一次。有人可以知道为什么会发生这种情况吗?我用沙盒和非沙盒应用程序尝试了所有这些,没有区别。我正在使用 10.8 sdk 在 ML 上进行开发。
编辑
现在避免这个问题的唯一方法是实现
panel:validateURL:error
,但这是在用户单击“打开”后调用的,这非常糟糕。 最佳答案
我有完全相同的问题,在 10.9 下,非沙盒化,并且在这一天的大部分时间里都在试图找到解决方案!
在对构成 NSOpenPanel
的各种类进行了大量修改和深入研究后(确实是 NSSavePanel
),我确实找到了一种方法来强制底层表自行刷新:
id table = [[[[[[[[[[[[_openPanel contentView] subviews][4] subviews][0] subviews][0] subviews][0] subviews][7] subviews][0] subviews][1] subviews][0] subviews][0] subviews][0] subviews][2];
[table reloadData];
当然,编写此 hack 的最佳方法是遍历 subview 列表,确保找到正确的类,并最终为后续的
reloadData
调用缓存结束表 View 。我知道,我知道,这是一个非常丑陋的组合,但是,除了“提交错误报告”之外,我似乎找不到任何其他答案来解决该问题。其中,从我所看到的网上人们自 1.8 以来一直在做什么! :(
编辑:
这是我现在用来使我的 NSOpenPanel 在 10.9 下正确运行的代码:
- (id) openPanelFindTable: (NSArray*)subviews;
{
id table = nil;
for (id view in subviews) {
if ([[view className] isEqualToString: @"FI_TListView"]) {
table = view;
break;
} else {
table = [self openPanelFindTable: [view subviews]];
if (table != nil) break;
}
}
return table;
}
- (void) refreshOpenPanel
{
if (_openPanelTableHack == nil)
_openPanelTableHack = [self openPanelFindTable: [[_openPanel contentView] subviews]];
[_openPanelTableHack reloadData];
[_openPanel validateVisibleColumns];
}
此代码需要声明两个实例变量
_openPanel
和 _openPanelTableHack
才能工作。我将 _openPanel
声明为 NSOpenPanel*
并且 _openPanelTableHack
声明为 id
。现在,我不是调用
[_openPanel validateVisibleColumns]
,而是调用 [self refreshOpenPanel]
来强制面板按预期更新文件名。我尝试在创建 NSOpenPanel 时缓存表 View ,但是,似乎一旦您“运行”面板,表 View 就会更改,因此我必须在第一次更新时缓存它。同样,这是一个 GIANT hack,但是,我不知道 Apple 需要多长时间才能解决附件 View 和文件面板的问题,所以现在,这是有效的。
如果有人有任何其他不是大杂烩的解决方案,请分享! ;)
关于objective-c - NSOpenPanel(不)validateVisibleColumns,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18192986/