簡體   English   中英

將綁定傳遞給 SwiftUI 視圖的 UIKit UIViewController

[英]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屬性不是正確的方法,我不確定。

SwiftUI 流程:

ContentView (present)→ DetailView
        ◟________________◞
             Binding

UIKit 流程:

ViewController (present)→ DetailView_UIKit → DetailView
                               ◟________________◞
                          Binding? Not sure what to put

謝謝你的幫助!

所以事實證明你不能在UIViewControllerView之間使用Binding

最后,我只是在DetailView做了一個可選的閉包。

  • 如果我提供DetailView_UIKit ,我會將閉包分配給一個解除函數,但傳入Binding (無論如何你不能)。
  • 如果我直接呈現DetailView ,我會像以前一樣傳入Binding ,但不會分配閉包。

然后,當我按下DetailView的按鈕時,我會嘗試

  1. Binding設置為 false
  2. 調用閉包

順序無關緊要,因為其中之一將始終為零。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM