簡體   English   中英

可以從托管的 SwiftUI 視圖調用 UIKit UIViewController 中的閉包嗎?

[英]Is it ok to call closures in UIKit UIViewController from Hosted SwiftUI View?

我在WrapperViewController托管ContentView ,如下所示:

class WrapperViewController: UIViewController {
    
    init() {
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func loadView() {
        
        self.view = UIView()

        var contentView = ContentView()
        contentView.buttonTapped = { [weak self] in
            self?.tappedButton()
        }
        
        let contentViewController = UIHostingController(rootView: contentView)
        
        self.addChild(contentViewController)
        self.view.addSubview(contentViewController.view)

        contentViewController.view.frame = view.bounds
        contentViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        contentViewController.didMove(toParent: self)
    }
    
    func tappedButton() {
        print("tapped button")
    }
}

struct ContentView: View {
    var buttonTapped: (() -> Void)?
    
    var body: some View {
        Button("Tap me") {
            buttonTapped?()
        }
    }
}

我正在從ContentView調用buttonTapped中的WrapperViewController ,但這可以嗎? “點擊按鈕”正在打印,但我讀了這篇文章

當您在結構中使用閉包時,閉包表現為引用類型,問題由此開始。 閉包需要引用外部環境,以便在執行閉包主體時可以修改環境。

 struct Car { var speed: Float = 0.0 var increaseSpeed: (() -> ())? } var myCar = Car() myCar.increaseSpeed = { myCar.speed += 30 // The retain cycle occurs here. We cannot use [weak myCar] as myCar is a value type. }

那么我應該在這里使用閉包嗎? 還是我應該做點別的?

我們不能使用 [weak myCar],因為 myCar 是一個值類型。

在文章的示例中, myCar是一個struct

但是,在您的代碼中:

contentView.buttonTapped = { [weak self] in
    self?.tappedButton()
}

self是一個UIViewController ,它是一個(和一個引用類型)。

您對[weak self]的使用非常好:閉包將保持對 UIViewController 的弱引用,當您點擊按鈕時,將tappedButton()函數。 這可能是您所期望的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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