Xcode 10 - NSVisualEffectView 在模态显示时添加到 NSWindow (Mac OS)
Xcode 10 - NSVisualEffectView added to NSWindow when displayed modally (Mac OS)
我有一个 NSWindow,我在其他 window 上以模态方式显示以显示警报。
代码是:
// This code is in MyAlert .m file. MyAlert inherits from NSWindow
- (void)showInWindow:(NSWindow *) {
[window beginSheet:self completionHandler:NULL];
}
问题是,当在 Mac 运行 Mojave 中使用 Xcode 10.1 编译时,我在警报后面看到一个灰色的 "blurring" 视图,我不希望出现在那里: 我希望背景 window 在显示的位置可见。
使用 Xcode 9.4.1 编译的相同代码不会显示此模糊视图。
此外,我调试了UI,在Xcode10.1编译版本中确实插入了一个NSVisualEffectView,在9.4.1上编译时没有,但我似乎找不到一种摆脱它的方法。
以下是在两个版本中调试的 UI 的屏幕截图。
有人面对并解决了这个问题吗?
更新(插入的 nsvisualeffectview 的最小项目重现问题):http://s000.tinyupload.com/?file_id=43114618701497778758
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
__weak typeof(self)weakSelf = self;
NSView *contentView = self.window.contentView;
contentView.wantsLayer = YES;
[self.window setOpaque:NO];
[self.window setHasShadow:NO];
contentView.layer.backgroundColor = [NSColor redColor].CGColor;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
__strong typeof(weakSelf) strongSelf = weakSelf;
[strongSelf showAlert];
});
}
- (void)showAlert {
DummyAlertWindowController *alertController = [[DummyAlertWindowController alloc] initWithWindowNibName:@"DummyAlertWindowController"];
[self.window beginSheet:alertController.window completionHandler:^(NSModalResponse returnCode) {
;
}];
}
@implementation DummyAlertWindowController
- (void)windowDidLoad {
[super windowDidLoad];
self.properContentView.wantsLayer = YES;
self.properContentView.layer.backgroundColor = [NSColor blueColor].CGColor;
[self.window setOpaque:NO];
[self.window setHasShadow:NO];
self.window.contentView.wantsLayer = YES;
self.window.contentView.layer.backgroundColor = [NSColor clearColor].CGColor;
}
@end
您可以通过 window 无边框来恢复未磨砂的外观。
将此 class 添加到您的项目中。
@interface BorderlessWindow : NSWindow
@end
@implementation BorderlessWindow
- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSWindowStyleMask)style backing:(NSBackingStoreType)backingStoreType defer:(BOOL)flag {
self = [super initWithContentRect:contentRect
styleMask:NSWindowStyleMaskBorderless
backing:backingStoreType
defer:flag];
return self;
}
@end
然后将 XIB
中的 window class 设置为 BorderlessWindow
最后在 window 上设置 backgroundColor
以获得透明度。
@implementation DummyAlertWindowController
- (void)windowDidLoad {
[super windowDidLoad];
//stuff
[self.window setOpaque:NO];
[self.window setHasShadow:NO];
[self.window setBackgroundColor:[NSColor clearColor]];
}
@end
附带说明一下,使用 wantsLayer
获取 backgroundColors 现在可以通过使用带有自定义颜色的自定义样式 NSBox
或使用 backgroundColor
属性 window.
我有一个 NSWindow,我在其他 window 上以模态方式显示以显示警报。 代码是:
// This code is in MyAlert .m file. MyAlert inherits from NSWindow
- (void)showInWindow:(NSWindow *) {
[window beginSheet:self completionHandler:NULL];
}
问题是,当在 Mac 运行 Mojave 中使用 Xcode 10.1 编译时,我在警报后面看到一个灰色的 "blurring" 视图,我不希望出现在那里: 我希望背景 window 在显示的位置可见。
使用 Xcode 9.4.1 编译的相同代码不会显示此模糊视图。
此外,我调试了UI,在Xcode10.1编译版本中确实插入了一个NSVisualEffectView,在9.4.1上编译时没有,但我似乎找不到一种摆脱它的方法。 以下是在两个版本中调试的 UI 的屏幕截图。
有人面对并解决了这个问题吗?
更新(插入的 nsvisualeffectview 的最小项目重现问题):http://s000.tinyupload.com/?file_id=43114618701497778758
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
__weak typeof(self)weakSelf = self;
NSView *contentView = self.window.contentView;
contentView.wantsLayer = YES;
[self.window setOpaque:NO];
[self.window setHasShadow:NO];
contentView.layer.backgroundColor = [NSColor redColor].CGColor;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
__strong typeof(weakSelf) strongSelf = weakSelf;
[strongSelf showAlert];
});
}
- (void)showAlert {
DummyAlertWindowController *alertController = [[DummyAlertWindowController alloc] initWithWindowNibName:@"DummyAlertWindowController"];
[self.window beginSheet:alertController.window completionHandler:^(NSModalResponse returnCode) {
;
}];
}
@implementation DummyAlertWindowController
- (void)windowDidLoad {
[super windowDidLoad];
self.properContentView.wantsLayer = YES;
self.properContentView.layer.backgroundColor = [NSColor blueColor].CGColor;
[self.window setOpaque:NO];
[self.window setHasShadow:NO];
self.window.contentView.wantsLayer = YES;
self.window.contentView.layer.backgroundColor = [NSColor clearColor].CGColor;
}
@end
您可以通过 window 无边框来恢复未磨砂的外观。
将此 class 添加到您的项目中。
@interface BorderlessWindow : NSWindow
@end
@implementation BorderlessWindow
- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSWindowStyleMask)style backing:(NSBackingStoreType)backingStoreType defer:(BOOL)flag {
self = [super initWithContentRect:contentRect
styleMask:NSWindowStyleMaskBorderless
backing:backingStoreType
defer:flag];
return self;
}
@end
然后将 XIB
中的 window class 设置为 BorderlessWindow
最后在 window 上设置 backgroundColor
以获得透明度。
@implementation DummyAlertWindowController
- (void)windowDidLoad {
[super windowDidLoad];
//stuff
[self.window setOpaque:NO];
[self.window setHasShadow:NO];
[self.window setBackgroundColor:[NSColor clearColor]];
}
@end
附带说明一下,使用 wantsLayer
获取 backgroundColors 现在可以通过使用带有自定义颜色的自定义样式 NSBox
或使用 backgroundColor
属性 window.