[英]Is it ok to call closures in UIKit UIViewController from Hosted SwiftUI View?
[英]UIKit UIViewController that passes a Binding to a SwiftUI View
我正在嘗試在 UIKit 中提供 SwiftUI View
。 目前,有一個Binding<Bool>
用於關閉/呈現DetailView
。 這是工作代碼:
struct ContentView: View {
@State var presentingModal = false
var body: some View {
Button("Present") { self.presentingModal = true } /// tap button to present detail sheet
.sheet(isPresented: $presentingModal) {
DetailView(isPresentedBinding: $presentingModal) /// pass in the binding
}
}
}
struct DetailView: View {
var isPresented: Binding<Bool>? /// it's an optional so I do this instead of `@Binding var isPresented: Bool`
var body: some View {
Button("Done") { isPresented?.wrappedValue = false } /// tap the "Done" button to dismiss
}
}
當您按下“完成”按鈕時,它isPresented
設置為 false,從而關閉工作表。 現在我想從UIViewController
呈現DetailView
。 這是我到目前為止:
class ViewController: UIViewController {
@IBAction func presentButtonPressed(_ sender: Any) {
let detailViewController = DetailView_UIKit()
self.present(detailViewController, animated: true, completion: nil)
}
}
/// wrap DetailView in a ViewController so it's easier to present
class DetailView_UIKit: UIViewController {
init() {
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func loadView() {
view = UIView()
/// Host the `DetailView`
let detailViewController = UIHostingController(
rootView: DetailView() /// I need to pass a Binding in here!
)
self.addChild(detailViewController)
view.addSubview(detailViewController.view)
detailViewController.view.frame = view.bounds
detailViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
detailViewController.didMove(toParent: self)
}
/// I want to call this function too
func dismissThisViewController() {
self.dismiss(animated: true, completion: nil)
}
}
這有效,但“完成”按鈕沒有做任何事情...... Binding
仍然為零,因為我沒有將它分配給任何東西。 如何在DetailView_UIKit
創建某種@State
屬性,以便我可以將其傳遞給DetailView
? 當該屬性設置為false
時,我希望調用dismissThisViewController
。 或者也許創建@State
屬性不是正確的方法,我不確定。
ContentView (present)→ DetailView
◟________________◞
Binding
ViewController (present)→ DetailView_UIKit → DetailView
◟________________◞
Binding? Not sure what to put
謝謝你的幫助!
UIViewController
和View
之間使用Binding
。 最后,我只是在DetailView
做了一個可選的閉包。
DetailView_UIKit
,我會將閉包分配給一個解除函數,但不傳入Binding
(無論如何你不能)。DetailView
,我會像以前一樣傳入Binding
,但不會分配閉包。 然后,當我按下DetailView
的按鈕時,我會嘗試
Binding
設置為 false順序無關緊要,因為其中之一將始終為零。
DetailView
:
struct DetailView: View {
var isPresented: Binding<Bool>? /// Optional `Binding` from before
var donePressed: (() -> Void)? /// The optional closure I just added
var body: some View {
Button("Done") {
/// Attempt to set the `Binding` (dismiss the `.sheet` if SwiftUI)
isPresented?.wrappedValue = false
/// Attempt to call the closure (call the `self.dismiss` if UIKit)
donePressed?()
}
}
}
DetailView_UIKit
:
override func loadView() {
view = UIView()
/// Host the `DetailView`
let detailViewController = UIHostingController(
rootView: DetailView() /// I DO NOT pass in a `Binding` here!
)
/// Assign the closure!
detailViewController.donePressed = { [weak self] in
self?.dismissThisViewController()
}
self.addChild(detailViewController)
view.addSubview(detailViewController.view)
detailViewController.view.frame = view.bounds
detailViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
detailViewController.didMove(toParent: self)
}
/// Call this function in the closure
func dismissThisViewController() {
self.dismiss(animated: true, completion: nil)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.