High Sierra 更新导致 NSTableView 翻转和打乱

Posted

技术标签:

【中文标题】High Sierra 更新导致 NSTableView 翻转和打乱【英文标题】:High Sierra update causes NSTableView to flip and scramble 【发布时间】:2017-08-18 20:06:42 【问题描述】:

我正在将一个多年来运行良好的现有项目更新到 High Sierra。视图正确加载并且看起来像往常一样:

然后,在我打开一个弹出窗口并再次关闭它后,视图会移动东西,翻转东西,并且通常看起来很疯狂:

请注意,信息标题下降到底部,左侧文本项倒序,日期和下拉文本翻转。发生这种情况时,鼠标交互似乎也很混乱。

我不知道从哪里开始解决这个问题,有人有什么想法吗?

这是使用 xcode 9 beta 5 和 High Sierra Beta 6。 更新:这也在 xcode 9 GM 和 High Sierra GM 种子中

更新

我已经确定当我在该视图所在的 NSTableView 上调用 reloadData 时会发生这种情况。所以现在的问题似乎是如何刷新表格数据而不会出现问题。

【问题讨论】:

看起来好像某些视图改变了它的 Y 方向。我不知道新 SDK 中 NSView 的“翻转”属性是否发生了变化,但我会检查您的代码是否使用它(覆盖 isFlipped)。 @Sashah。嗨,我对 reloadData() 和 CAShapeLayers、NSImageView 有类似的问题。 reloadData() 影响出现在 NSImageView 中的 CAShapeLayers。看起来 NSTableView 的 reloadData() 是 High Sierra 中更普遍的问题。 ***.com/questions/46423303/… 我在生产 High Sierra 中看到了同样的问题 还在 10.13.2 更新中... 我找到了解决办法。在执行对 reloadData() 的调用后,我在主线程上调用以将表视图的宽度调整为 1.0(使用约束),经过短暂的延迟。然后,在又一个短暂的延迟之后,我恢复了约束更改。当您看到反转的文本时,有一个非常小的时刻,但除此之外它有效。 【参考方案1】:

似乎 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];

如果有更好的答案,我仍然希望看到它。

【讨论】:

嗨,我也有同样的问题,遗憾的是,您的解决方案仅部分适用于我......在我实施您的解决方案之前,我的所有单元格都将变得不可见,现在只有显示的单元格可见但当我向下滚动时,其他的仍然不可见。第二次刷新后,所有单元格再次不可见。你有什么建议吗? 我只是在猜测,但可能没有在滚动条上调用 refreshAllCells? WO 有点难看,但确实有效!你拯救了我的一天;-)【参考方案2】:

对我来说,在我的子类中添加 WantUpdateLayer 解决了这个问题。

override open var wantsUpdateLayer: Bool return true

【讨论】:

【参考方案3】:

在 IB 中,勾选复选框以在 tableView 的视图上使用 CALayers。我为 tableView 视图层次结构中的所有视图打开了它们,所有翻转都停止了!

无法发布图片,因为我没有足够的声誉,但此链接显示 IB 复选框:

【讨论】:

这没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,provide answers that don't require clarification from the asker。 - From Review 第一句回答了问题,优雅地解决了问题。我想发布一张图片以清楚地突出显示要检查的 Interface Builder 选项,但无法检查。然而,链接确实链接到图像,所以我觉得它是我可以给出的最完整的答案。 感谢另一个节点!【参考方案4】:

我也遇到了这个错误,在实现 another answer 时,我发现了这个错误的真正原因,因为现在引发了一个异常:

在我的例子中,reloadData 被调用再次,而reloadData 仍在执行中。这导致了渲染问题。

“循环”是在 tableView(_:, viewFor:, row:) 中调用 tableView.makeView(withIdentifier: identifier, owner: self) 的副作用。 owner: self 导致控制器的awakeFromNib() 再次被调用,这反过来又触发了reloadData()。在我的设置中,我没有(还)为表格单元格使用单独的 XIB,而是使用在表格视图中设置的单元格作为可见的界面生成器。

因此解决方案是将tableView.makeView(withIdentifier: identifier, owner: self) 更改为tableView.makeView(withIdentifier: identifier, owner: nil),并为表格单元格使用单独的XIB。

【讨论】:

【参考方案5】:

我在 10.13 中也看到了这一点,当时 10.12 工作得很好。奇怪的是,我能够通过在其[layout] 中重新添加单元格视图的子视图来解决此问题:

- (void)layout
    if([self needsLayout])
        for(NSView* v in [[self subviews] copy])
            [self addSubview:v];
        
    

    [super layout];

【讨论】:

【参考方案6】:

我也经历过。进一步的测试表明,在更新 tableview 数据源时正在绘制内容。通过消除虚假更新,我能够消除问题。

我在 draw 方法中重新加载数据,但是我已将数据更新代码移到该方法之外。不确定这是否有助于 OP,但它对我有用。

【讨论】:

【参考方案7】:

突然间,我收到了几封来自客户的邮件,他们抱怨所有表格文本都垂直翻转。他们都使用 macOS Mojave。

经过大量黑客攻击,并尝试了上面详述的解决方案(可惜无济于事),我决定禁用 NSTableView 的 autoSave 属性:

//Swift.print("Now setting autosaveName of primaryView to \(self.className).primary")
//primaryTableView.autosaveName = "\(self.className).primary"
//primaryTableView.autosaveTableColumns = true

然后问题立即消失了。但现在我的客户无法再更改和保存列宽和顺序。因此,不要以编程方式使用 tableView.autosaveName = "autosavename";我现在在表格视图属性中设置了 autoSave 属性,并在属性检查器中检查了“列信息”(同时显示 xib 文件)。然后它就可以正常工作了..

我使用当前最新版本的 Xcode (10.1 10B61),问题仅在使用 macOS Mojava 10.14.0 - 10.14.2 时出现。高塞拉利昂和塞拉利昂没有遇到任何麻烦。无论我是在 High Sierra 还是 Mojave 编译项目,都没有区别。

所以,我希望这对面临这个奇怪问题的其他人有所帮助。我认为这是 macOS Mojave 中的一个错误。

【讨论】:

唉,几天后打开应用程序几次,不知何故问题又回来了。我现在已经在整个应用程序中完全禁用了自动保存功能,现在它似乎已永久解决。我认为 macOS Mojave 在处理(至少)NSTableView 的自动保存属性时存在错误。保存列设置几次后,首选项(.plist)文件中的某些内容似乎损坏(或至少引发了错误),并且 macOS Mojave 不知何故认为它必须翻转 NSTableView 中的所有单元格。因此,目前,除了禁用自动保存属性之外没有其他解决方案。【参考方案8】:

有同样的问题,可在 High Sierra 和 Mojave 上重现。问题出在 NSOutlineView autosaveName 上,其他解决方案没有帮助。但是我需要这个功能。

将添加/重新加载数据移动到“viewDidAppear()”而不是“viewDidLoad()”解决了这个问题。

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

    存在自动保存 在应用排序之前,项目会在 viewDidLoad 上加载 应用排序后会重新加载相同的项目列表 以上所有情况都发生在 viewDidLoad

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

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

【讨论】:

以上是关于High Sierra 更新导致 NSTableView 翻转和打乱的主要内容,如果未能解决你的问题,请参考以下文章

2011年的macos+high+sierra如何更新系统?

Mac git pull失败,最新操作系统导致 SSH issues with Mac OS X High Sierra

Paragon更新了对macOS High Sierra的Microsoft NTFS支持

macmac os X更新High Sierra后出现的问题

macOS Mojave:从 High Sierra 更新到 Mojave 后,活动开发者路径无效

Xcode 9.3 和更新到 High Sierra:即使完全重新安装,仪器也无法打开 *.tracetemplate 文件