Swift and SwiftUI Products Help Contact

SwiftUI macOS Vibrancy

Since macOS 11 Big Sur, Vibrancy has been part of the macOS user interface, and most apps will take advantage of it where they can. It's not an earth shattering effect, but when used correctly it can help make a UI look similar to Apple's own apps.

Ventura and Xcode 15.2. Published: May 19th 2025

Applying SwiftUI Vibrancy

Getting Vibrancy is easy with SwiftUI, sidebars, inspectors and sheets automatically use vibrancy. For other situations, simply apply a Material to the background of a view and SwiftUI handles the rest.

struct ContentView: View { var body: some View { HStack( spacing: 0 ){ Test_Controls() Test_Controls() .background(.ultraThinMaterial) } .frame( width: 500 ) } }

SwiftUI uses "thickness" as it's Material options, instead of semantic naming (sidebar, sheet, etc). .ultraThinMaterial has the most pronounced effect.

Something doesn't feel right

While it was easy to make a panel vibrant in SwiftUI, I had this pit of the stomach feeling that it wasn't matching AppKit apps. So I made a comparison. SwiftUI on the right and the AppKit NSVisualEffectView on the left.

HStack( spacing: 0 ){ Test_Controls() .background(VisualEffectView(material: .sidebar)) Test_Controls() .background(.ultraThinMaterial) }

The NSVisualEffectView is allowing more blending of what's behind the window, while the native SwiftUI seems to use just a hint of the desktop picture. When compared like this, it doesn't even look like the right hand side has any vibrancy.

But... Adding a NSVisualEffectView, doesn't make the controls vibrant, only the background.

The code to use AppKit's NSVisualEffectView in SwiftUI is below.

import AppKit import SwiftUI public struct VisualEffectView: NSViewRepresentable { var material: NSVisualEffectView.Material var blending: NSVisualEffectView.BlendingMode = .behindWindow public func makeNSView(context: Context) -> some NSVisualEffectView { let view = NSVisualEffectView() view.material = material view.blendingMode = blending return view } public func updateNSView(_ nsView: NSViewType, context: Context) {} }

Hybrid solution

The solution was to use both, SwiftUI's vibrancy on an enclosing ZStack and a NSVisualEffectView to match AppKit made apps.

HStack( spacing: 0 ){ ZStack{ Test_Controls() .background(VisualEffectView(material: .sidebar)) } .background(.ultraThinMaterial) Test_Controls() .background(.ultraThinMaterial) }

Is this a bug in SwiftUI on the macOS?

Honestly as I was preparing to write up a bug report, I came to the conclusion that it might be intentional. No other Apple platform is windowed quite like the macOS, so the SwiftUI vibrancy is meant to use the content of the application or window (but it is different to setting the blending mode of a NSVisualEffectView to window content blending). If Apple had made the blending match AppKit on the Mac it would be inconsistent with iOS, watchOS, tvOS, iPadOS etc.

However I do think Apple should have made some Materials just for the macOS that match AppKit. Apple Feedback case: FB17381328.

Bonus: Vibrant label colors

AppKit offers 4 different colors that you can use for labels and custom elements, SwiftUI Colors, only contain 2 .primary and .secondary.

The other two colors are not colors, they're styles instead.

Text( "Primary Text" ) .foregroundStyle( Color.primary ) Text( "Secondary Text" ) .foregroundStyle( Color.secondary ) Text( "Tertiary Text" ) .foregroundStyle( .tertiary ) Text( "Quaternary Text" ) .foregroundStyle( .quaternary )
  • Sleep Aid, our Mac Sleep troublshooter See what your Mac does when it should be asleep - Sleep Aid
  • Ohanaware © 2007 - 2025 Ohanaware Co., Ltd. Registered in Taiwan R.O.C. 🇹🇼
    Site managed by Strawberry Software's Lifeboat - running on DigitalOcean's platform.

    Pages

    Products Contact Weblog SwiftUI Promos

    Company

    About Us Environment Privacy Terms Update Plans

    Connect

    Bluesky Facebook Threads X / Twitter Mailing List