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()" 解决了问题。

已编辑: 它仅在以下情况下发生:

  1. 存在自动保存
  2. 在应用排序之前,项目在 viewDidLoad 上加载
  3. 应用排序后重新加载相同的项目列表
  4. 以上所有发生在 viewDidLoad

如果您尝试访问 tableView.sortingDescriptors(或 NSOutlineView)- 它会自动应用排序。如果它发生在加载数据之前 - 它工作正常。

在 viewDidAppear 上加载数据看起来仍然是更好的选择。