Dun*_*n C 13 macos osx-mavericks nsvisualeffectview
即将推出的OSX 10.10("Yosemite")提供了一种新型视图NSVisualEffectView,它支持窗口内或窗口内的半透明效果.我对窗口的半透明感兴趣,所以我将在这个问题中专注于这一点,但它也适用于窗口内的半透明度.
在10.10中使用窗口半透明是微不足道的.您只需NSVisualEffectView
在视图层次结构中放置一个位置并将其设置blendingMode
为NSVisualEffectBlendingModeBehindWindow
.这就是全部.
在10.10下你可以NSVisualEffectView
在IB中定义s,设置它们的混合模式属性,然后你就可以开始运行了.
但是,如果您希望向后兼容早期的OSX版本,则无法执行此操作.如果您尝试NSVisualEffectView
在XIB中包含一个,则在尝试加载XIB时会立即崩溃.
我想要一个"设置并忘记它"的解决方案,它将在10.10下运行时提供半透明效果,并且在早期操作系统版本上运行时简单地降级为不透明视图.
到目前为止我所做的是在XIB中使有问题的视图成为普通的NSView,然后添加检查的代码(由awakeFromNib调用),[NSVisualEffectView class] != nil
当它被定义时,我创建了一个NSVisualEffectView的实例,将我当前视图的所有子视图移动到新视图,并将其安装到位.这是有效的,但它是我每次想要半透明视图时必须编写的自定义代码.
我想这可能是使用NSProxy对象.这就是我的想法:
定义NSView的自定义子类(让我们称之为MyTranslucentView).在所有的init方法(initWithFrame和initWithCoder)中,我会抛弃新创建的对象,而是创建一个具有私有实例变量(myActualView)的NSProxy子类.在初始时间,将决定以创建myActualView对象作为NSVisualEffectView如果OS> = 10.10,和OS下一个正常的NSView <10.10.
代理会将所有消息转发给myActualView.
这将是相当多的繁琐,低级代码,但我认为它应该工作.
有没有人做过这样的事情?如果是这样,你能指出我正确的方向还是给我任何指示?
苹果是MUCH更加开放与约塞米蒂一个测试版协议比以前的Beta版本.通过谈论这一点,我不认为我违反了我的Beta NDA,但实际使用的代码NSVisualEffectView
可能需要在NDA下共享...
Jak*_*ger 11
有一个非常简单但有点hacky的解决方案:只需动态创建一个NSVisualEffectView
应用程序启动时命名的类.然后,您可以加载包含该类的nib,并在OS X 10.9及更早版本上使用优雅的回退.
这是我的app委托的摘录,用于说明这个想法:
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
Run Code Online (Sandbox Code Playgroud)
您必须针对OS X 10.10 SDK进行编译.
它是如何工作的?
当您的应用程序在10.9及更早版本上运行时,[NSVisualEffectView class]
将为NULL.在这种情况下,以下两行创建一个NSView
没有方法的子类,没有名称的ivars NSVisualEffectView
.
因此,当AppKit现在NSVisualEffectView
从nib文件中取消归档时,它将使用您新创建的类.该子类的行为与NSView相同.
但为什么一切都不会火上浇油?
当视图从nib文件中取消归档时,它会使用NSKeyedArchiver
.关于它的好处是它只是忽略了对应于属性/ ivars的其他键NSVisualEffectView
.
还有什么我需要小心的吗?
NSVisualEffectView
代码中的任何属性(例如material
)之前,请确保该类响应选择器([view respondsToSelector:@selector(setMaterial:)]
)[[NSVisualEffectView alloc] initWithFrame:]
仍然无法工作,因为类名在编译时解析.要么使用[[NSClassFromString(@"NSVisualEffectView") alloc] initWithFrame:]
,要么只分配NSView
if [NSVisualEffectView class]
为NULL. 归档时间: |
|
查看次数: |
3592 次 |
最近记录: |