06 January 2023
Adding Blur Effects to a macOS App using SwiftUI
I recently started learning SwiftUI to build a new project called Xnappit targeted at macOS and it has been quite a ride learning Swift and SwiftUI.
SwiftUI is a powerful framework for building native apps on Apple platforms. One of the great things about SwiftUI is its ability to work seamlessly with AppKit and UIKit, the frameworks used for building Mac and iOS apps respectively. In this blog post, we’ll take a look at how to use a NSVisualEffectView in a SwiftUI app using NSViewRepresentable.
A NSVisualEffectView is a view that provides a blur effect to the content behind it. It’s a useful tool for adding depth and polish to your app’s interface.
To use a NSVisualEffectView in a SwiftUI app, we’ll need to create a custom View type that conforms to the NSViewRepresentable protocol. In the example below we create a struct called BlurredView
which conforms to the NSViewRepresentable
protocol. This protocol has two methods that we’ll need to implement: makeNSView(context:)
and updateNSView(_:context:)
.
import SwiftUI
struct BlurView: NSViewRepresentable {
...
}
The makeNSView(context:)
method is called when the view is first created. Here, we can create a new NSVisualEffectView
instance and configure it as needed. In the example below, we set the material property to .sidebar
and the blendingMode property to .behindWindow
.
func makeNSView(context: Context) -> some NSVisualEffectView {
let view = NSVisualEffectView()
view.material = .sidebar
view.blendingMode = .behindWindow
return view
}
The updateNSView(_:context:)
method is called when the view’s state changes. In this method, we can update the NSVisualEffectView instance with the new state. In the example below, the method is left empty since the view’s state isn’t changing.
func updateNSView(_ nsView: NSViewType, context: Context) {
}
With these two methods implemented we have the following:
import SwiftUI
struct BlurredView: NSViewRepresentable {
func makeNSView(context: Context) -> some NSVisualEffectView {
let view = NSVisualEffectView()
view.material = .sidebar
view.blendingMode = .behindWindow
return view
}
func updateNSView(_ nsView: NSViewType, context: Context) {
}
}
We can now use our BlurredView
struct as a regular SwiftUI view. Simply add it to your view hierarchy like any other view, and the blur effect will be applied to the content behind it. Here we add it as a background of a VStack
.
struct ContentView: View {
var body: some View {
VStack {
Text("Hello, World!")
}.background(BlurredView()).frame(width: 300, height: 300)
}
}
Using NSViewRepresentable is a great way to leverage the power of AppKit and UIKit in your SwiftUI apps. It allows you to use familiar UI components and techniques, while still taking advantage of the declarative syntax and improved performance of SwiftUI.