【问题标题】:How can I create Yosemite-style view with translucent/blurry background?如何创建具有半透明/模糊背景的优胜美地风格的视图?
【发布时间】:2014-07-24 06:17:21
【问题描述】:

在 Yosemite 中,侧边栏有一个半透明的“充满活力”的背景。如何在 10.10/Xcode 6 中创建这样的视图?

我可以给出这样的背景吗?我发现NSOutlineView 在你给它“源列表”突出显示样式时会默认为这样的背景,但是 Calendar.app 中的侧边栏似乎不是 NSOutlineView,所以我想知道是否有一个通用的解决方案这个。

【问题讨论】:

    标签: macos interface-builder nsview osx-yosemite


    【解决方案1】:

    w00t!我发现 example code 使用尚未记录的视图类型:

    1. 将 XIB 的部署目标设置为 10.10
    2. NSVisualEffectView 中嵌入您的视图
    3. 在 Interface Builder 的视图设置中,将外观设置为“Vibrant Light/Dark”。还有其他选项,例如混合“Behind Window”或“Within Window”(后者需要图层)。

    还有 NSView 方法 allowsVibrancy 可以覆盖以返回 YES,但由于我还不明白的原因,这在我的情况下并没有启用活力。

    【讨论】:

    • allowsVibrancy 用于更改视图在使用活力的视图层次结构中的绘制方式;它本身并没有做充满活力的背景。
    • 对于寻找 was able to achieve it partially on a window,而不是整个窗口。但是,我可以添加半透明颜色,但高斯模糊似乎对提供窗后风格的扩散/活力没有任何影响 - 窗后的所有内容都清晰可见,只是从半透明颜色变暗。
    • @ConfusedVorlon 的答案与此相同,除了在代码中,并允许优雅的回退,以便需要在 10.10 之前的 OSX 上运行构建的人可以拥有一个代码库(无需一个 fork),它将在 Yosemite 及更高版本上启用该功能,但在 Yosemite 之前禁用该功能。
    • 我在系统偏好设置/辅助功能中关闭了“降低透明度”。在经过数小时的反复试验后,我发现没有任何效果
    【解决方案2】:

    随着 OSX 操作系统 Yosemite 版本的推出,Apple 为 Cocoa 窗口和窗口组件引入了一种名为 vibrancy 的新模式,即光漫射模糊。这有点像透过淋浴门看,并使用NSVisualEffectView。苹果explains this effect here.

    我在 NSView 上使用这个类别。 只需调用您想要使其充满活力的视图。 它还向后兼容 pre-Yosemite。 (如果你有pre-Yosemite,你就看不到效果了)

    @implementation NSView (HS)
    
    -(instancetype)insertVibrancyViewBlendingMode:(NSVisualEffectBlendingMode)mode
    {
        Class vibrantClass=NSClassFromString(@"NSVisualEffectView");
        if (vibrantClass)
        {
            NSVisualEffectView *vibrant=[[vibrantClass alloc] initWithFrame:self.bounds];
            [vibrant setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
            // uncomment for dark mode instead of light mode
            // [vibrant setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantDark]];
            [vibrant setBlendingMode:mode];
            [self addSubview:vibrant positioned:NSWindowBelow relativeTo:nil];
            
            return vibrant;
        }
    
        return nil;
    }
    
    @end
    

    来自@Volomike 的详细说明如下……

    如何使用

    1. AppKit.framework 添加到您的项目设置 > 构建阶段 > Link Binary with Libraries 以便它可以识别 NSVisualEffectView。

    2. 为您的 AppDelegate.m 或 AppDelegate.mm 文件制作主窗口默认视图出口代理,而不是窗口本身. (如果您是新手,read this tutorial。)出于此处的目的,我们假设您将其命名为 mainview,然后在代码中可寻址为 _mainview

    3. 在您的项目中包含类别。如果您是新手,请在 AppDelegate.m 或 AppDelegate.mm 文件中的任何 @implementation 行之前添加类别。

    4. 在您的 AppDelegate.m 或 AppDelegate.mm 文件中,在您的 @implementation AppDelegate 中,在您的 applicationDidFinishLaunching 类方法中,添加这行代码:: p>

    [_mainview insertVibrancyViewBlendingMode:NSVisualEffectBlendingModeBehindWindow];
    
    1. 现在您需要学习如何添加一些代码以赋予窗口上的其他元素以及窗口本身半透明。这种半透明性将允许这种效果根据您的需要显示到您的窗口组件中。这是explained here

    现在的最终效果是,标题栏下方的整个窗口或仅您想要的部分(例如侧边栏)都会显示这种活力效果。

    【讨论】:

    • 很抱歉,如何在 pre yosemite 构建中实现这一点?我什至无法编译它。
    • 将 FX 视图置于内容视图下方会导致奇怪的字体渲染伪影(平滑是在错误的背景下完成的)。我发现在 FX 视图中嵌入内容视图更好。
    • @zoul 有截图的机会吗?我很想看看字体渲染的区别。 (我不太清楚问题是什么)
    • 我已经核对了我的示例项目,但是在 Apple 开发者论坛的 this thread 中有一些相关问题的屏幕截图。
    • @Volomik 感谢您的编辑。我对其进行了一些调整,以将答案和您的教程分开。我通常不会解释诸如类别之类的概念,或者如何获得对您的观点的参考(IB Outlets 只是一种方式) - 但如果这对人们有帮助,它可以留在底部。
    【解决方案3】:

    只需使用NSVisualEffectView。您可以使用其字段进一步调整它,如下所示:

    class MyFancyView: NSVisualEffectView {
        func myConfigureFunc() {
    
            // Use blendingMode to specify what exactly is blurred
    
            blendingMode = .behindWindow // [DEFAULT] ignores in-window content and only blurs content behind the window
            blendingMode = .withinWindow // ignores content behind the window and only blurs in-window content behind this view
    
    
            // Use material to specify how the blur draws (light/dark/etc.)
    
            material = .light           // The Vibrant Light look we see in countless Apple apps' sidebars, Sierra notification center, etc.
            material = .dark            // The Vibrant Dark look we all know and love from HUDs, Launchpad, Yosemite & El Capitan notification center, etc.
    
            material = .appearanceBased // [DEFAULT] Automatically uses .light or .dark, depending on the view's appearance field
    
            material = .titlebar        // The material the system uses in titlebars. Designed to be used with blendingMode = .withinWindow
            material = .selection       // A special material for selection. The material will vary depending on the effectiveAppearance, active state, and emphasized state.
    
            if #available(OSX 10.11, *) {
    
                // Materials introduced in 10.11 (El Capitan)
    
                material = .mediumLight // Not quite as light as .light
                material = .ultraDark   // Much darker than .dark
    
                material = .menu        // The material the system uses for menus
                material = .popover     // The material the system uses for popovers
                material = .sidebar     // The material the system uses for sidebars
            }
    
    
            // Use state to specify when the visual effect appears
    
            state = .active                   // Always show the visual effect
            state = .inactive                 // Never show the visual effect (behaves like a normal view)
            state = .followsWindowActiveState // [DEFAULT] Active when window is active, not when window is not
        }
    }
    

    观看 Apple 官方视频了解更多信息:WWDC 2014 Session 220

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-25
      • 1970-01-01
      • 1970-01-01
      • 2015-11-05
      • 1970-01-01
      • 2018-05-30
      • 2021-03-06
      相关资源
      最近更新 更多