gpt4 book ai didi

cocoa - NSImageView 始终显示在任何其他类型的 View 之上

转载 作者:行者123 更新时间:2023-12-03 17:01:10 24 4
gpt4 key购买 nike

我正在开发一个数据库应用程序,它有一个与 Interface Builder 非常相似的图形编辑器。然而,与 IB 不同的是,该编辑器可以从编辑器模式翻转到实时模式,其中用户界面是完全可操作的(可以单击按钮、编辑文本等)。为此,图形编辑器使用标准 Appkit 界面类 - NSButton、NSTextView等。编辑器本身是用NSView的自定义子类实现的。所有用户界面元素都是此自定义 NSView 的 subview ,使用 addSubview: 方法添加新元素,使新元素成为最顶层的可见元素(注意 - View 不受图层支持,只是常规 View )。用户还可以使用“Bring-to-Front”和“Send-to-Back”命令来更改 subview 的顺序。该影片展示了两个重叠的 NSButton 元素(出于说明目的,当然通常情况下您永远不会重叠它们),以及程序如何重新排列 subview 以更改用户界面元素的 Z 顺序。

Bring-to-Front, Send-to-Back

问题是,这适用于除 NSImageView 之外的各种界面元素。之前的电影中有两个元素,一个 NSButton 和一个 NSImageView。 NSButton 实际上一直在“顶部”,NSImageView 元素应该出现在按钮后面,但无论 subview 的顺序如何,NSImageView 总是出现在顶部。

NSImageView always on top

如果有两个重叠的 NSImageView 对象,它们之间的可见堆叠顺序是不可预测的,但它们始终会出现在所有其他对象之上,无论 subview 的顺序如何。

一个可能有用的线索是,如果我实现自己的自定义 View ,直接在其 drawRect: 方法中绘制图像,那么效果很好。所以这是一个可能的解决方案,但我不愿意,因为这意味着重新实现 NSImageView 通常负责的大量有用功能,其中一些非常复杂,例如支持动画 GIF 显示。除了这个分层/z 顺序问题之外,有关 NSImageView 的其他所有内容都工作正常。

也许 NSImageView 在我没有要求的情况下使用了图层支持,因此它没有与我的其他对象正确混合?我找不到任何表明这一点的文档。我没有链接到 QuartzCore 框架。

以下代码将 NSImageView 元素作为 subview 添加到图形编辑器 View 中。

- (void)objectDidAppearBelow:(NSView *)nextView
{
FormView * formView = [FormWindowController currentFormView]; // get view element will be placed into
NSScrollView * imageContainer = [[NSScrollView alloc] initWithFrame:insideBorderRect];
ImageView * ixView = [[ImageView alloc] initWithFrame:[self insideFormObjectBorder:objectRectangle]];
[ixView setOwnerObject:self];
[imageContainer setDocumentView:ixView];
[imageContainer setAutoresizesSubviews:YES];
[shapeView addSubview:imageContainer Below:nextView];
imageDocumentView = ixView; // save weak reference to image view so it can be manipulated
}

在其他地方,NSButton(有几种变体,用于按钮、单选按钮等)、NSTextView、NSTableView(用于列表和矩阵)、NSSlider、NSScroller、NSSegmentedControl,甚至 WebView 都有几乎相同的代码。所有其他都可以正确处理重叠对象,包括 WebView,只有 NSImageView 无法按预期工作。

供我引用,这是 Panorama X 问题跟踪器中的#429。

最佳答案

我在 WWDC 2018 上与 Apple 工程师讨论了这个问题。事实证明,正如我所怀疑的那样,在某些情况下,即使您没有要求,Appkit 也会为 NSImageView 使用图层支持!因此,最好的解决方案是将所有 View 切换到图层支持(这将在 Mojave 中自动发生)。

在这种特殊情况下,NSImageView 位于 NSScrollView 内,我没有提及它,因为我认为它不重要(我的错)。事实证明,在这种情况下,Appkit 认为使用层支持将是一个好主意(以优化滚动)。因此,解决此问题的另一种方法是子类化 NSImageView(由于其他原因我已经这样做了)并添加此方法(由一位不愿透露姓名的 Apple 工程师当场编写)。

+ (BOOL)isCompatibleWithResponsiveScrolling {
if (NSAppKitVersionNumber <= 1561. /* NSAppKitVersionNumber10_13 */) {
return NO;
} else {
return YES;
}
}

我确信这都是公开的、有记录的 API 的一部分,尽管文档很少(令人惊讶)。 What's new in OS X 10.9中有一些关于响应式滚动的讨论。发行说明。对 NSAppKitVersionNumber 的检查是为了确保在 Mojave 上运行时关闭此补丁,因为一切都是层支持的。

关于cocoa - NSImageView 始终显示在任何其他类型的 View 之上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50561950/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com