[英]Accessing Value of SwiftUI View through a UIKit View
我在網上閱讀了這個問題,發現它非常有趣。 如果您有如下所示的 SwiftUI 視圖。 如何在不更改 RatingView 中的一行的情況下訪問 UIKit 視圖中的選定評分。
struct RatingView: View {
@Binding var rating: Int?
private func starType(index: Int) -> String {
if let rating = rating {
return index <= rating ? "star.fill" : "star"
} else {
return "star"
}
}
var body: some View {
HStack {
ForEach(1...5, id: \.self) { index in
Image(systemName: self.starType(index: index))
.foregroundColor(Color.orange)
.onTapGesture {
rating = index
}
}
}
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
// .constant(3) will be replaced by something in the ViewController so it can handle the changes for the rating
let hostingController = UIHostingController(rootView: RatingView(rating: .constant(3)))
guard let ratingsView = hostingController.view else { return }
self.addChild(hostingController)
self.view.addSubview(ratingsView)
}
更新:
原文來源: https ://twitter.com/azamsharp/status/1540838477599752192?s=20&t=bbDp3VT9m0Ce4W3Sgr7Iyg
我從原始來源輸入了大部分代碼。 我沒有太大變化。
我們可以裝飾 RatingView 並使用 ObservableObject 來保持事實的來源。
class RatingObserver: ObservableObject {
@Published var rating: Int?
}
struct WrappedRatingView: View {
@ObservedObject var ratingObserver: RatingObserver
var body: some View {
RatingView(rating: $ratingObserver.rating)
}
}
然后我們可以通過以下方式使用它。
class ViewController: UIViewController {
let ratingObserver = RatingObserver()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
let hostingController = UIHostingController(
rootView: WrappedRatingView(ratingObserver: ratingObserver)
)
self.addChild(hostingController)
view.addSubview(hostingController.view)
hostingController.didMove(toParent: self)
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("Reset Rating", for: .normal)
button.setTitleColor(.blue, for: .normal)
button.addTarget(self, action: #selector(resetRating), for: .touchUpInside)
view.addSubview(button)
NSLayoutConstraint.activate([
hostingController.view.centerXAnchor.constraint(equalTo: view.centerXAnchor),
hostingController.view.centerYAnchor.constraint(equalTo: view.centerYAnchor),
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 100)
])
}
@objc func resetRating() {
ratingObserver.rating = nil
}
}
這允許更新 ViewController 和 SwiftUI 視圖。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.