How to set addObserver in SwiftUI?

前端 未结 6 2154
眼角桃花
眼角桃花 2021-02-13 16:35

How do I add NotificationCenter.default.addObserve in SwiftUI?

When I tried adding observer I get below error

Argument of \'#sele

相关标签:
6条回答
  • 2021-02-13 17:10

    This worked for me

       let NC = NotificationCenter.default
    
    
    
       self.NC.addObserver(forName: .NEVPNStatusDidChange, object: nil, queue: nil, 
                           using: self.VPNDidChangeStatus)
    
    
       func VPNDidChangeStatus(_ notification: Notification) {
    
    
        }
    
    0 讨论(0)
  • 2021-02-13 17:17

    I use this extension so it's a bit nicer on the call site:

    /// Extension
    
    extension View {
        func onReceive(_ name: Notification.Name,
                       center: NotificationCenter = .default,
                       object: AnyObject? = nil,
                       perform action: @escaping (Notification) -> Void) -> some View {
            self.onReceive(
                center.publisher(for: name, object: object), perform: action
            )
        }
    }
    
    /// Usage
    
    struct MyView: View {
        var body: some View {
            Color.orange
                .onReceive(.myNotification) { _ in
                    print(#function)
                }
        }
    }
    
    extension Notification.Name {
        static let myNotification = Notification.Name("myNotification")
    }
    
    
    0 讨论(0)
  • 2021-02-13 17:19

    The accepted answer may work but is not really how you're supposed to do this. In SwiftUI you don't need to add an observer in that way.

    You add a publisher and it still can listen to NSNotification events triggered from non-SwiftUI parts of the app and without needing combine.

    Here as an example, a list will update when it appears and when it receives a notification, from a completed network request on another view / controller or something similar etc.

    If you need to then trigger an @objc func for some reason, you will need to create a Coordinator with UIViewControllerRepresentable

    struct YourSwiftUIView: View {
    
        let pub = NotificationCenter.default
                .publisher(for: NSNotification.Name("YourNameHere"))
    
    
        var body: some View {
            List() {
                ForEach(userData.viewModels) { viewModel in
                    SomeRow(viewModel: viewModel)
                }
            }
            .onAppear(perform: loadData)
            .onReceive(pub) { (output) in
                self.loadData()
            }
        }
    
        func loadData() {
            // do stuff
        }
    }
    
    0 讨论(0)
  • 2021-02-13 17:26

    I have one approach for NotificationCenter usage in SwiftUI.

    For more information Apple Documentation

    Notification extension

    extension NSNotification {
        static let ImageClick = NSNotification.Name.init("ImageClick")
    }
    

    ContentView

    struct ContentView: View {
        var body: some View {
            VStack {
                DetailView()
            }
            .onReceive(NotificationCenter.default.publisher(for: NSNotification.ImageClick))
            { obj in
               // Change key as per your "userInfo"
                if let userInfo = obj.userInfo, let info = userInfo["info"] {
                  print(info)
               }
            }
        }
    }
    

    DetailView

    struct DetailView: View {
        var body: some View {
            Image(systemName: "wifi")
                .frame(width: 30,height: 30, alignment: .center)
                .foregroundColor(AppColor.black)
                .onTapGesture {
                    NotificationCenter.default.post(name: NSNotification.ImageClick, 
                                                    object: nil, userInfo: ["info": "Test"])
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-13 17:33

    It is not SwiftUI-native approach, which is declarative & reactive. Instead you should use NSNotificationCenter.publisher(for:object:) from Combine.

    See more details in Apple Documentation

    0 讨论(0)
  • 2021-02-13 17:35

    exchange this

    self.NC.addObserver(self, selector: #selector(self.VPNDidChangeStatus),
                              name: .NEVPNStatusDidChange, object: nil) 
    

    to

    self.NC.addObserver(self, selector: #selector(VPNDidChangeStatus(_:)),
                              name: .NEVPNStatusDidChange, object: nil)
    
    0 讨论(0)
提交回复
热议问题