admin管理员组

文章数量:1279189

I was using Terminal on macOS when something caught my eye. I saw that the Terminal app allows users to update the blur radius, not just the opacity! I found this super cool and want to adapt this functionality to my app to allow my users to update the blur radius. I started defining a basic app and needed variables and code to make this happen, but the closest I got was being able to update the opacity, which is not what I want. I want to update the blur radius like in the video. How can I do it?

import Cocoa
import SwiftUI
import Combine

// Protocol to manage blur effect updates
protocol BlurEffectUpdatable {
    func updateBlurEffect(radius: CGFloat)
}

class AppDelegate: NSObject, NSApplicationDelegate, BlurEffectUpdatable {
    
    private lazy var window: NSWindow = NSWindow()
    private var blurEffect: NSVisualEffectView = NSVisualEffectView()
    private var blurManager = BlurManager()  // Initialize BlurManager here
    
    private var cancellables: Set<AnyCancellable> = []
    
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        window.styleMask = [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView]
        window.backingType = .buffered
        window.isReleasedWhenClosed = false
        window.center()
        window.setFrameAutosaveName("Main Window")
        window.title = "My Blur"
        window.isMovableByWindowBackground = true
        window.backgroundColor = .clear
        
        // Create the blur effect
        blurEffect = NSVisualEffectView()
        blurEffect.blendingMode = .behindWindow
        blurEffect.material = .hudWindow
        blurEffect.state = .active
        blurEffect.autoresizingMask = [.width, .height]
        
        // Observe changes to radius in BlurManager and update the blur effect accordingly
        blurManager.$radius
            .sink { [weak self] radius in
                self?.updateBlurEffect(radius: radius)
            }
            .store(in: &cancellables)

        let hostingView = NSHostingView(rootView: ContentView(blurManager: blurManager)) 
        hostingView.translatesAutoresizingMaskIntoConstraints = false
        
        let containerView = NSView()
        containerView.addSubview(blurEffect)
        containerView.addSubview(hostingView)
        
        blurEffect.frame = containerView.bounds
        hostingView.frame = containerView.bounds
        
        NSLayoutConstraint.activate([
            hostingView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor),
            hostingView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor)
        ])
        
        window.contentView = containerView
        window.makeKeyAndOrderFront(nil)
    }
    
    // Conform to the BlurEffectUpdatable protocol
    func updateBlurEffect(radius: CGFloat) {
        print(radius)
        // I want the blur radius get updated not opacity!
        blurEffect.layer?.opacity = Float(radius/20.0)

    }
}



struct ContentView: View {
    @ObservedObject var blurManager: BlurManager
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            
            Text("Hello, world!")
            
            // Slider for adjusting the blur radius
            Slider(value: $blurManager.radius, in: 0...20, step: 1.0) {
                Text("Blur Radius")
            }
            .padding()
            
            Text("Blur Radius: \(blurManager.radius, specifier: "%.1f")")
        }
        .frame(width: 400, height: 200)
    }
}

// BlurManager class to manage the blur radius
class BlurManager: ObservableObject {
    @Published var radius: CGFloat = 10.0
}

I am using a main.swift file to run the app on macOS 12.7.6 with Xcode 14.2 and a minimum deployment target of 12.0.

本文标签: swiftHow to to update the blur radius of NSVisualEffectViewStack Overflow