【问题标题】:Adjust NSVisualEffectView blur radius and transparency调整 NSVisualEffectView 模糊半径和透明度
【发布时间】:2016-05-14 20:30:40
【问题描述】:

NSVisualEffectView 应用于 NSWindow(Swift 或 Objective-C)时,是否可以调整其模糊半径和透明度?我尝试了NSVisualEffectMaterial 的所有变体(深色、中等、浅色)——但这并没有减少它。在下图中,我使用了 Apple 的非公共 API,左侧为 CGSSetWindowBackgroundBlurRadius,右侧为 NSVisualEffectView

我正在尝试实现左侧的外观,但似乎我被降级为使用右侧的方法。

这是我的代码:

blurView.blendingMode = NSVisualEffectBlendingMode.BehindWindow
blurView.material = NSVisualEffectMaterial.Medium
blurView.state = NSVisualEffectState.Active
self.window!.contentView!.addSubview(blurView)

可能,相关 - 但没有回答我的问题:

【问题讨论】:

    标签: swift macos cocoa


    【解决方案1】:

    虽然我不建议这样做,除非您准备好退回到它在未来的版本中不起作用,但您可以将 NSVisualEffectView 子类化为以下内容来做您想做的事情:

    - (void)updateLayer
    {
        [super updateLayer];
    
        [CATransaction begin];
        [CATransaction setDisableActions:YES];
    
        CALayer *backdropLayer = self.layer.sublayers.firstObject;
    
        if ([backdropLayer.name hasPrefix:@"kCUIVariantMac"]) {
            for (CALayer *activeLayer in backdropLayer.sublayers) {
                if ([activeLayer.name isEqualToString:@"Active"]) {
                    for (CALayer *sublayer in activeLayer.sublayers) {
                        if ([sublayer.name isEqualToString:@"Backdrop"]) {
                            for (id filter in sublayer.filters) {
                                if ([filter respondsToSelector:@selector(name)] && [[filter name] isEqualToString:@"blur"]) {
                                    if ([filter respondsToSelector:@selector(setValue:forKey:)]) {
                                        [filter setValue:@5 forKey:@"inputRadius"];
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    
        [CATransaction commit];
    }
    

    虽然这本身不使用私有 API,但它确实开始挖掘您不拥有的层级结构,因此请务必仔细检查您返回的内容是否符合您的预期,如果不是,请优雅地失败.例如,在 10.10 Yosemite 上,Backdrop 层是 Visual Effect 视图的直接继承者,因此未来可能会发生变化。

    【讨论】:

    • 您好,感谢您的回答,但不幸的是,这似乎根本没有调整透明度。
    • 这个例子是在窗口内模糊的,所以你可能需要在层的层次结构中寻找你想要的特定层。在updateLayer 中设置断点,并不断调用po self.layer.sublayers 以查看您需要在视觉效果视图中搜索的内容。方便的是,大多数图层都已命名,因此您可以像这样一点一点地向下钻取。我相信还有一个名为Tint 的层也可以控制颜色。
    【解决方案2】:

    我遇到了和你一样的问题,我已经用一个小技巧解决了这个问题,似乎可以完成我想要的工作。希望对你也有帮助。

    所以在我的例子中,我在情节提要中添加了NSVisualEffectView 并将其属性设置如下:

    我的视图层次结构如下:

    所有减少模糊的东西都在 NSViewController 中:

    override func viewWillAppear() {
        super.viewWillAppear()
        //Adds transparency to the app
        view.window?.isOpaque = false
        view.window?.alphaValue = 0.98 //tweak the alphaValue for your desired effect
    }
    

    与您的示例一起,此代码应与上述调整一起使用:

        let blurView = NSVisualEffectView(frame: view.bounds)
        blurView.blendingMode = .behindWindow
        blurView.material = .fullScreenUI
        blurView.state = .active
        view.window?.contentView?.addSubview(blurView)
    

    Swift 5 代码 对于任何对此感兴趣的人来说,我的 repo 的链接我创建了一个使用上面代码的小型恶作剧应用程序: GitHub link

    【讨论】:

      猜你喜欢
      • 2015-11-05
      • 1970-01-01
      • 1970-01-01
      • 2010-09-30
      • 1970-01-01
      • 1970-01-01
      • 2016-03-10
      • 1970-01-01
      • 2011-08-31
      相关资源
      最近更新 更多