I have a UIKit project with UIViewControllers, and I'd like to present an action sheet built on SwiftUI from my ViewController. I need to bind the appearance and disappearance of the action sheet back to the view controller, enabling the view controller to be dismissed (and for the display animation to happen only on viewDidAppear, to avoid some weird animation behavior that happens when using .onAppear
). Here is a code example of how I expect the binding to work and how it's not doing what I'm expecting:
import UIKit
import SwiftUI
class ViewController: UIViewController {
let button = UIButton(type: .system)
var show = true
lazy var isShowing: Binding<Bool> = .init {
self.show
} set: { show in
// This code gets called
self.show = show
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
button.setTitle("TAP THIS BUTTON", for: .normal)
view.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
button.addTarget(self, action: #selector(tapped), for: .touchUpInside)
}
@objc private func tapped() {
let vc = UIHostingController(rootView: BindingProblemView(testBinding: isShowing))
vc.modalPresentationStyle = .overCurrentContext
present(vc, animated: false)
DispatchQueue.main.asyncAfter(deadline: .now() + 5) { [self] in
isShowing.wrappedValue.toggle()
isShowing.update()
}
}
}
struct BindingProblemView: View {
@Binding var testBinding: Bool
@State var state = "ON"
var body: some View {
ZStack {
if testBinding {
Color.red.ignoresSafeArea().padding(0)
} else {
Color.green.ignoresSafeArea().padding(0)
}
Button("Test Binding is \(state)") {
testBinding.toggle()
}.onChange(of: testBinding, perform: { value in
// This code never gets called
state = testBinding ? "ON" : "OFF"
})
}
}
}
What happens is that onChange
never gets called after viewDidAppear
when I set the binding value true
. Am I just completely misusing the new combine operators?