Integrating UIKit with SwiftUI - How to trigger event inside UIKit in SwiftUI level?

2020-02-16

Everything in SwiftUI is driven by state updates. As we follow the official tutorial or the tutorial published by Raywenderlich, we can easily bind states between SwiftUI and UIKit. But there is still one thing unresolved. That is, how can we trigger the event inside UIKit in SwiftUI level? (For example, a button that calls a function inside UIViewRepresentable) I’ve found a solution: We declare a state which is closure type. And we bind it to the UIViewRepresentable or UIViewControllerRepresentable. In makeUIView or makeUIViewController function, we can reassign the closure, make it work properly. But when we assign a new value to the binding state directly in these functions, Xcode complains: “Modifying state during view update, this will cause undefined behavior“. This is reasonable because we should not directly change a state during view updating(But what we are doing now actually not affecting the result of the view). So what should we do? In this article, the author takes lots of experiments. After reading that, we know there exactly is a solution, using DispatchQueen. In another asynchronous thread, we can do our job.

DispatchQueue.main.async {
    self.anyClosureState = {
        // the real jobs
    }
}