High Sierra 更新导致 NSTableView 翻转和乱码
High Sierra update causes NSTableView to flip and scramble
我正在将一个多年来运行良好的现有项目更新到 High Sierra。视图正确加载并且看起来一如既往:
然后,在我打开一个弹出窗口并再次关闭它之后,视图会四处移动、翻转,而且通常看起来很疯狂:
请注意信息标题下降到底部,左侧文本项目倒序,日期和下拉文本翻转。发生这种情况时,鼠标交互似乎也很混乱。
我不知道从哪里开始解决这个问题,有人有什么想法吗?
这是使用 xcode 9 beta 5 和 High Sierra Beta 6。
更新:这也在 xcode 9 GM 和 High Sierra GM Seed 中
更新
我确定当我在该视图所在的 NSTableView 上调用 reloadData 时会发生这种情况。所以现在的问题似乎是如何刷新 table 数据而不会不稳定。
似乎 reloadData 和 reloadDataForRowIndexes:columnIndexes: 都在 High Sierra 中产生了奇怪的行为。我的解决方法如下:
-(void)refreshAllCells {
NSMutableIndexSet* rowIndexes = [[NSMutableIndexSet alloc] init];
if (self.myTable.numberOfRows != 0)
[rowIndexes addIndexesInRange:NSMakeRange(0, (self.myTable.numberOfRows))];
[self.myTable removeRowsAtIndexes:rowIndexes withAnimation:NO];
[self.myTable insertRowsAtIndexes:rowIndexes withAnimation:NO];
}
如果有更好的答案我还是很想看
我在 10.13 中也看到了这一点,当时 10.12 工作得很好。奇怪的是,我能够通过在 [layout]
:
中重新添加单元格视图的子视图来解决这个问题
- (void)layout{
if([self needsLayout]){
for(NSView* v in [[self subviews] copy]){
[self addSubview:v];
}
}
[super layout];
}
我也遇到过这种情况。进一步的测试表明,在更新 tableview 数据源时正在绘制内容。通过消除虚假更新,我能够消除该问题。
我在 draw 方法中重新加载数据,但是我已将数据更新代码移到该方法之外。不确定这是否对 OP 有帮助,但对我有用。
对我来说,在我的子类中添加 wantsUpdateLayer 解决了这个问题。
override open var wantsUpdateLayer: Bool {
return true
}
在 IB 中,勾选复选框以在 tableView 的视图上使用 CALayers。我为 tableView 视图层次结构中的所有视图打开了它们,所有翻转都停止了!
无法 post 图片,因为我没有足够的声誉,但是这个 link 显示了 IB 复选框:
突然之间,我收到了几封来自客户的邮件,他们抱怨所有 table 文本都被垂直翻转显示。他们都使用 macOS Mojave。
经过大量的黑客攻击,并尝试了上面详述的解决方案(唉,无济于事),我决定禁用 NSTableView:
的自动保存 属性
//Swift.print("Now setting autosaveName of primaryView to \(self.className).primary")
//primaryTableView.autosaveName = "\(self.className).primary"
//primaryTableView.autosaveTableColumns = true
然后问题瞬间解决了。但现在我的客户无法再更改和保存列宽和顺序。因此,与其以编程方式使用 tableView.autosaveName = "autosavename";我现在在 Table 视图属性中设置了 autoSave 属性,并且还在属性检查器中检查了 'Column information'(同时显示 xib 文件)。然后它工作得很好..
我使用的是当前最新版本的Xcode (10.1 10B61),问题只在使用macOS Mojava 10.14.0 - 10.14.2 时出现。 High Sierra 和 Sierra 没有遇到任何麻烦。无论我在 High Sierra 还是 Mojave 中编译该项目都没有区别。
所以,我希望这对遇到这个奇怪问题的其他人有所帮助。我认为这是 macOS Mojave 中的一个错误。
我也遇到了这个错误,在实施 时,我发现了错误的真正原因是现在引发了一个异常:
在我的例子中,reloadData
再次被调用 ,而 reloadData
仍在执行。这导致了渲染问题。
"loop" 是在 tableView(_:, viewFor:, row:)
中调用 tableView.makeView(withIdentifier: identifier, owner: self)
的副作用。 owner: self
导致再次调用控制器 awakeFromNib()
,进而触发 reloadData()
。在我的设置中,我(还)没有为 table 单元格使用单独的 XIB,而是使用在 table 视图中设置的单元格作为可见的 Interface Builder。
所以解决方案是将 tableView.makeView(withIdentifier: identifier, owner: self)
更改为 tableView.makeView(withIdentifier: identifier, owner: nil)
并为 table 单元格使用单独的 XIB。
有同样的问题,可在 High Sierra 和 Mojave 重现。问题出在 NSOutlineView autosaveName 上,其他解决方案没有帮助。但是我需要这个功能。
将 adding/reloading 数据移动到 "viewDidAppear()" 而不是 "viewDidLoad()" 解决了问题。
已编辑:
它仅在以下情况下发生:
- 存在自动保存
- 在应用排序之前,项目在 viewDidLoad 上加载
- 应用排序后重新加载相同的项目列表
- 以上所有发生在 viewDidLoad
如果您尝试访问 tableView.sortingDescriptors(或 NSOutlineView)- 它会自动应用排序。如果它发生在加载数据之前 - 它工作正常。
在 viewDidAppear 上加载数据看起来仍然是更好的选择。
我正在将一个多年来运行良好的现有项目更新到 High Sierra。视图正确加载并且看起来一如既往:
然后,在我打开一个弹出窗口并再次关闭它之后,视图会四处移动、翻转,而且通常看起来很疯狂:
请注意信息标题下降到底部,左侧文本项目倒序,日期和下拉文本翻转。发生这种情况时,鼠标交互似乎也很混乱。
我不知道从哪里开始解决这个问题,有人有什么想法吗?
这是使用 xcode 9 beta 5 和 High Sierra Beta 6。
更新:这也在 xcode 9 GM 和 High Sierra GM Seed 中
更新
我确定当我在该视图所在的 NSTableView 上调用 reloadData 时会发生这种情况。所以现在的问题似乎是如何刷新 table 数据而不会不稳定。
似乎 reloadData 和 reloadDataForRowIndexes:columnIndexes: 都在 High Sierra 中产生了奇怪的行为。我的解决方法如下:
-(void)refreshAllCells {
NSMutableIndexSet* rowIndexes = [[NSMutableIndexSet alloc] init];
if (self.myTable.numberOfRows != 0)
[rowIndexes addIndexesInRange:NSMakeRange(0, (self.myTable.numberOfRows))];
[self.myTable removeRowsAtIndexes:rowIndexes withAnimation:NO];
[self.myTable insertRowsAtIndexes:rowIndexes withAnimation:NO];
}
如果有更好的答案我还是很想看
我在 10.13 中也看到了这一点,当时 10.12 工作得很好。奇怪的是,我能够通过在 [layout]
:
- (void)layout{
if([self needsLayout]){
for(NSView* v in [[self subviews] copy]){
[self addSubview:v];
}
}
[super layout];
}
我也遇到过这种情况。进一步的测试表明,在更新 tableview 数据源时正在绘制内容。通过消除虚假更新,我能够消除该问题。
我在 draw 方法中重新加载数据,但是我已将数据更新代码移到该方法之外。不确定这是否对 OP 有帮助,但对我有用。
对我来说,在我的子类中添加 wantsUpdateLayer 解决了这个问题。
override open var wantsUpdateLayer: Bool {
return true
}
在 IB 中,勾选复选框以在 tableView 的视图上使用 CALayers。我为 tableView 视图层次结构中的所有视图打开了它们,所有翻转都停止了!
无法 post 图片,因为我没有足够的声誉,但是这个 link 显示了 IB 复选框:
突然之间,我收到了几封来自客户的邮件,他们抱怨所有 table 文本都被垂直翻转显示。他们都使用 macOS Mojave。
经过大量的黑客攻击,并尝试了上面详述的解决方案(唉,无济于事),我决定禁用 NSTableView:
的自动保存 属性//Swift.print("Now setting autosaveName of primaryView to \(self.className).primary")
//primaryTableView.autosaveName = "\(self.className).primary"
//primaryTableView.autosaveTableColumns = true
然后问题瞬间解决了。但现在我的客户无法再更改和保存列宽和顺序。因此,与其以编程方式使用 tableView.autosaveName = "autosavename";我现在在 Table 视图属性中设置了 autoSave 属性,并且还在属性检查器中检查了 'Column information'(同时显示 xib 文件)。然后它工作得很好..
我使用的是当前最新版本的Xcode (10.1 10B61),问题只在使用macOS Mojava 10.14.0 - 10.14.2 时出现。 High Sierra 和 Sierra 没有遇到任何麻烦。无论我在 High Sierra 还是 Mojave 中编译该项目都没有区别。
所以,我希望这对遇到这个奇怪问题的其他人有所帮助。我认为这是 macOS Mojave 中的一个错误。
我也遇到了这个错误,在实施
在我的例子中,reloadData
再次被调用 ,而 reloadData
仍在执行。这导致了渲染问题。
"loop" 是在 tableView(_:, viewFor:, row:)
中调用 tableView.makeView(withIdentifier: identifier, owner: self)
的副作用。 owner: self
导致再次调用控制器 awakeFromNib()
,进而触发 reloadData()
。在我的设置中,我(还)没有为 table 单元格使用单独的 XIB,而是使用在 table 视图中设置的单元格作为可见的 Interface Builder。
所以解决方案是将 tableView.makeView(withIdentifier: identifier, owner: self)
更改为 tableView.makeView(withIdentifier: identifier, owner: nil)
并为 table 单元格使用单独的 XIB。
有同样的问题,可在 High Sierra 和 Mojave 重现。问题出在 NSOutlineView autosaveName 上,其他解决方案没有帮助。但是我需要这个功能。
将 adding/reloading 数据移动到 "viewDidAppear()" 而不是 "viewDidLoad()" 解决了问题。
已编辑: 它仅在以下情况下发生:
- 存在自动保存
- 在应用排序之前,项目在 viewDidLoad 上加载
- 应用排序后重新加载相同的项目列表
- 以上所有发生在 viewDidLoad
如果您尝试访问 tableView.sortingDescriptors(或 NSOutlineView)- 它会自动应用排序。如果它发生在加载数据之前 - 它工作正常。
在 viewDidAppear 上加载数据看起来仍然是更好的选择。