gpt4 book ai didi

macos - 如何使用 NSVisualEffectView 向后兼容 OSX < 10.10?

转载 作者:行者123 更新时间:2023-12-03 23:44:00 24 4
gpt4 key购买 nike

即将推出的 OSX 10.10(“Yosemite”)提供了一种新型 View ,即 NSVisualEffectView,它支持通过窗口或窗口内的半透明。我最感兴趣的是通过窗口半透明,所以我将在这个问题中关注它,但它也适用于窗口内半透明。

在 10.10 中使用透窗半透明是微不足道的。您只需放置 NSVisualEffectView在您的 View 层次结构中的某处并将其设置为 blendingModeNSVisualEffectBlendingModeBehindWindow .这就是它所需要的。

在 10.10 下可以定义 NSVisualEffectView在 IB 中,设置它们的混合模式属性,然后您就可以开始运行了。

但是,如果您想向后兼容早期的 OSX 版本,则不能这样做。如果您尝试包含 NSVisualEffectView在您的 XIB 中,一旦您尝试加载 XIB,您就会崩溃。

我想要一个“设置它并忘记它”的解决方案,它在 10.10 下运行时会提供半透明效果,而在早期操作系统版本上运行时会简单地降级为不透明 View 。

到目前为止,我所做的是使有问题的 View 成为 XIB 中的普通 NSView,然后添加检查 [NSVisualEffectView class] != nil 的代码(由 awakeFromNib 调用) ,当它的类被定义时,我创建了一个 NSVisualEffectView 的实例,将我当前 View 的所有 subview 移动到新 View ,并将其安装到位。这行得通,但是每次我想要半透明 View 时,我都必须编写自定义代码。

我认为这可能使用 NSProxy 对象。这就是我的想法:

定义一个自定义的 NSView 子类(我们称之为 MyTranslucentView)。在所有初始化方法(initWithFrame 和 initWithCoder)中,我会丢弃新创建的对象,而是创建一个具有私有(private)实例变量(myActualView)的 NSProxy 子类。在初始化时,如果 OS>=10.10,它将决定将 myActualView 对象创建为 NSVisualEffectView,并在 OS<10.10 下创建正常的 NSView。

代理将转发 全部 给它的消息是 myActualView。

这将是相当繁琐的低级代码,但我认为它应该可以工作。

有没有人做过这样的事情?如果是这样,你能指出我正确的方向或给我任何指示吗?

苹果是 很多 与 Yosemite a 签订的 Beta 协议(protocol)比之前的 Beta 更开放。我不认为我通过笼统地谈论这个违反了我的 Beta NDA,但实际代码使用 NSVisualEffectView可能需要在 NDA 下共享...

最佳答案

有一个非常简单但有点 hacky 的解决方案:只需动态创建一个名为 NSVisualEffectView 的类当您的应用程序启动时。然后,您可以加载包含该类的 nib,并在 OS X 10.9 及更早版本上优雅地回退。

这是我的应用程序委托(delegate)的摘录来说明这个想法:

AppDelegate.m

#import "AppDelegate.h"
#import <objc/runtime.h>

@implementation PGEApplicationDelegate
-(void)applicationWillFinishLaunching:(NSNotification *)notification {
if (![NSVisualEffectView class]) {
Class NSVisualEffectViewClass = objc_allocateClassPair([NSView class], "NSVisualEffectView", 0);
objc_registerClassPair(NSVisualEffectViewClass);
}
}
@end

您必须针对 OS X 10.10 SDK 编译它。

它是如何工作的?

当您的应用在 10.9 及更早版本上运行时, [NSVisualEffectView class]将为 NULL。在这种情况下,以下两行创建了 NSView 的子类。没有方法也没有 ivars,名称为 NSVisualEffectView .

因此,当 AppKit 现在取消归档 NSVisualEffectView从 nib 文件中,它将使用您新创建的类。该子类的行为与 NSView 相同。

但为什么不是一切都火上浇油?

当 View 从 nib 文件中取消归档时,它使用 NSKeyedArchiver .它的好处是它只是忽略了与 NSVisualEffectView 的属性/ivars 相对应的其他键。 .

还有什么我需要注意的吗?
  • 在您访问 NSVisualEffectView 的任何属性之前在代码中(例如 material ),确保类响应选择器( [view respondsToSelector:@selector(setMaterial:)] )
  • [[NSVisualEffectView alloc] initWithFrame:]仍然无法工作,因为类名是在编译时解析的。使用 [[NSClassFromString(@"NSVisualEffectView") alloc] initWithFrame:] ,或者只是分配一个 NSView如果 [NSVisualEffectView class]一片空白。
  • 关于macos - 如何使用 NSVisualEffectView 向后兼容 OSX < 10.10?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25914918/

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