【问题标题】:SwiftUI with NotificationCenter publishers带有 NotificationCenter 发布者的 SwiftUI
【发布时间】:2020-01-01 12:26:07
【问题描述】:

我想在应用程序进入后台并返回时收听通知。我正在尝试使用 NotificationCenter 发布者并让 SwiftUI 视图收听它们。
我可以使用几种方法来做到这一点,并且我正在尝试使用其中的两种,但有趣的是,尽管当我将订阅者放入 init() 方法时,所有方法看起来都是合法的,但它只是不起作用。
我试图将它放在main 线程上,但仍然没有成功。
有谁知道为什么?
这是我的代码:

struct ContentView: View {
    @State var isActive = true
    @State var cancellables = Set<AnyCancellable>()
    var body: some View {
        ZStack {
            Image("background")
                .resizable()
                .scaledToFill()
                .edgesIgnoringSafeArea(.all)                        
        }
        .onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
            self.isActive = false
        }
        .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification), perform: {_ in
            self.isActive = true
        })
    }

    init() {
        NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)
         //   .receive(on: RunLoop.main)
            .sink(receiveValue: { _ in
                print("init")
            }
            .store(in: &cancellables)
    }
}

奇怪的是,onReceive 修饰符中的侦听器就像一个魅力。在init() 中,print("init") 永远不会被调用。

【问题讨论】:

    标签: swiftui combine notificationcenter


    【解决方案1】:

    @State 在 init 中还没有准备好,所以它不能用于这样的目的。方法可以如下:

    var cancellables = Set<AnyCancellable>()
    init() {
        NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)
            .sink(receiveValue: { _ in
                print(">> in init")
            })
            .store(in: &cancellables)
    }
    

    在这样定义的cancellables 中,您可以存储在init 中创建的所有订阅者,但您稍后将无法在代码中使用它,但这种方法适用于已定义的通知处理程序。

    【讨论】:

    • 谢谢,这似乎是问题所在。无论如何我都不想要@State 包装器,但在某个时候Xcode 开始抱怨在结构中你不能修改属性。但现在它接受了。
    【解决方案2】:

    你能用onAppear吗?

    ...
    ...
      var body: some View {
      ... your body code
      }.onAppear(perform: loadNotification)
    
      private func loadNotification() {
         NotificationCenter.default.publisher(
         ....
      }
    

    onAppear:

    https://developer.apple.com/documentation/swiftui/view/3278614-onappear

    好像是viewDidLoad的替代品

    【讨论】:

    • 我觉得更像viewDidAppear
    • 这个会被调用多次吗?如果是这样,该操作也将被触发多次
    猜你喜欢
    • 2021-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-28
    • 1970-01-01
    • 1970-01-01
    • 2020-06-14
    相关资源
    最近更新 更多