代码之家  ›  专栏  ›  技术社区  ›  Paul

SwiftUI macOs AppDelegate检测ObservedObject的更改

  •  0
  • Paul  · 技术社区  · 5 年前

    我有以下内容 AppDelegate 类,我想确定何时 userPreferences.backgroundIsTransparent 更改状态,必须调用内部的函数 AppDelegate .

    我看了一眼: https://stackoverflow.com/a/58431723/8024296

    但我不知道如何在我的情况下使用它。

    我该怎么办?

    AppDelegate:

    import Cocoa
    import SwiftUI
    
    @main
    class AppDelegate: NSObject, NSApplicationDelegate {
        var popover = NSPopover.init()
        var statusBar: StatusBarController?
        @Environment(\.colorScheme) var colorScheme
        
        @ObservedObject var userPreferences = UserPreferences.instance
        
        func applicationDidFinishLaunching(_ aNotification: Notification) {
            let contentView = ContentView()
            popover.contentSize = NSSize(width: 560, height: 360)
            popover.contentViewController = NSHostingController(rootView: contentView)
            statusBar = StatusBarController.init(popover)
            DistributedNotificationCenter.default.addObserver(self, selector: #selector(interfaceModeChanged(sender:)), name: NSNotification.Name(rawValue: "AppleInterfaceThemeChangedNotification"), object: nil)
        }
        
        func applicationWillTerminate(_ aNotification: Notification) {
            // Insert code here to tear down your application
        }
        
        @objc func interfaceModeChanged(sender: NSNotification) {
            //popover.backgroundColor = colorScheme == .dark ? #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1) : #colorLiteral(red: 0.2392156869, green: 0.6745098233, blue: 0.9686274529, alpha: 1)
            popover.backgroundColor = NSColor(named: "backgroundTheme")?.withAlphaComponent(userPreferences.backgroundIsTransparent ? 0.3 : 1.0)
            print("change", colorScheme)
        }
    }
    
    import EventKit
    import ServiceManagement
    
    private struct PreferencesKeys {
        static let backgroundIsTransparent = "backgroundIsTransparent"
        static let isDarkMode = "isDarkMode"
    }
    
    class UserPreferences: ObservableObject {
        static let instance = UserPreferences()
        
        private init() {
            // This prevents others from using the default '()' initializer for this class.
        }
        
        private static let defaults = UserDefaults.standard
        
        @Published var backgroundIsTransparent: Bool = {
            guard UserDefaults.standard.object(forKey: PreferencesKeys.backgroundIsTransparent) != nil else {
                return true
            }
            return UserDefaults.standard.bool(forKey: PreferencesKeys.backgroundIsTransparent)
        }() {
            didSet {
                UserPreferences.defaults.set(backgroundIsTransparent, forKey: PreferencesKeys.backgroundIsTransparent)
            }
        }
        
        @Published var isDarkMode: Bool = {
            guard UserDefaults.standard.object(forKey: PreferencesKeys.isDarkMode) != nil else {
                return true
            }
            return UserDefaults.standard.bool(forKey: PreferencesKeys.isDarkMode)
        }() {
            didSet {
                UserPreferences.defaults.set(isDarkMode, forKey: PreferencesKeys.isDarkMode)
            }
        }
        
    }
    
    0 回复  |  直到 5 年前
        1
  •  2
  •   vadian    5 年前

    有一种更复杂的观察方式 UserDefaults .

    这个 Combine 框架为 用户默认值 ,实际上是一个 关键价值观察出版商

    首先让你 backgroundIsTransparent 属性的扩展 用户默认值

    extension UserDefaults {
        @objc var backgroundIsTransparent: Bool {
            get {
                guard object(forKey: PreferencesKeys.backgroundIsTransparent) != nil else { return true }
                return bool(forKey: PreferencesKeys.backgroundIsTransparent)
            }
            set {
                set(newValue, forKey: PreferencesKeys.backgroundIsTransparent)
            }
        }
    }
    

    在AppDelegate中导入 结合 并创建 Set 订阅的

    import Combine
    
    @main
    class AppDelegate: NSObject, NSApplicationDelegate { ...
    
        private var subscriptions = Set<AnyCancellable>()
    

    和在 applicationDidFinishLaunching 添加发布者

        func applicationDidFinishLaunching(_ aNotification: Notification) {
    
        // .....
    
            UserDefaults.standard.publisher(for: \.backgroundIsTransparent)
                .sink { state in
                    print(state)
                    // do something with state
                }
                .store(in: &subscriptions)
        }
    

    使用您的方法的另一种选择是 userPreferences @StateObject

    @StateObject var userPreferences = UserPreferences.instance
    

    并观察 背景是透明的

    userPreferences.$backgroundIsTransparent
    .sink { state in
       print(state)
       // do something with state
    }
    .store(in: &subscriptions)
    
    推荐文章