如何在 SwiftUI 的视图控制器中实现数据绑定?
How do I implement data binding in a View Controller in SwiftUI?
我有一个 UIKit ViewController
,它使用 ViewControllerRepresentable
嵌套在 SwiftUI 视图中。 SwiftUI 视图管理我想在 UIKit 视图中显示的一些状态(在本例中为 Int
)。当用户点击 SwiftUI 父视图中的按钮时,状态更改应反映在 UIKit 视图中。我已经尝试使用 @Binding
属性 包装器使两者保持同步,但显然我遗漏了一些东西,因为我的视图控制器的初始化程序会引发编译时错误。
我对 iOS 开发还很陌生,所以我可能走错了方向。任何帮助将不胜感激。
代码如下(简化):
struct ContentView: View {
@State private var currentNumber: Int
init(currentNumber: Int) {
self.currentNumber = currentNumber
}
var body: some View {
FancyLabelViewControllerRepresentable(currentNumber: self.$currentNumber)
Button("Increment") {
self.currentNumber += 1
}
}
}
struct FancyLabelViewControllerRepresentable: UIViewControllerRepresentable {
typealias UIViewControllerType = FancyLabelViewController
@Binding var currentNumber: Int
init(currentNumber: Binding<Int>) {
self._currentNumber = currentNumber
}
func makeUIViewController(context: Context) -> FancyLabelViewController {
let fancyLabel = FancyLabelViewController(number: self.currentNumber)
fancyLabel.currentNumberInLabel = self.currentNumber
return fancyLabel
}
func updateUIViewController(_ uiViewController: FancyLabelViewController, context: Context) {
uiViewController.currentNumberInLabel = self.currentNumber
}
}
class FancyLabelViewController: UIViewController {
var label = UILabel()
@Binding var currentNumberInLabel: Int
init(number: Int) {
// Error: 'self' used in property access 'currentNumberInLabel' before 'super.init' call
self.currentNumberInLabel = number
// Error: Property 'self.currentNumberInLabel' not initialized at super.init call
super.init(nibName: nil, bundle: nil)
}
required init(coder: NSCoder) {
fatalError("Not implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
label.text = "\(currentNumberInLabel)"
view = label
}
}
我认为你不需要
@Binding var currentNumberInLabel: Int
因为 UIViewControllerRepresentable
已经负责更新 currentNumberInLabel
值,但您还需要更新
label.text = "\(currentNumberInLabel)"
所以我做了类似
的事情
class FancyLabelViewController: UIViewController {
var label = UILabel()
var currentNumberInLabel: Int
init(number: Int) {
self.currentNumberInLabel = number
super.init(nibName: nil, bundle: nil)
}
required init(coder: NSCoder) {
fatalError("Not implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
label.text = "\(currentNumberInLabel)"
view = label
}
func updateLabel() {
label.text = "\(currentNumberInLabel)"
}
}
并从 UIViewControllerRepresentable
调用 updateLabel
作为
func updateUIViewController(_ uiViewController: FancyLabelViewController, context: Context) {
uiViewController.currentNumberInLabel = self.currentNumber
uiViewController.updateLabel()
}
我有一个 UIKit ViewController
,它使用 ViewControllerRepresentable
嵌套在 SwiftUI 视图中。 SwiftUI 视图管理我想在 UIKit 视图中显示的一些状态(在本例中为 Int
)。当用户点击 SwiftUI 父视图中的按钮时,状态更改应反映在 UIKit 视图中。我已经尝试使用 @Binding
属性 包装器使两者保持同步,但显然我遗漏了一些东西,因为我的视图控制器的初始化程序会引发编译时错误。
我对 iOS 开发还很陌生,所以我可能走错了方向。任何帮助将不胜感激。
代码如下(简化):
struct ContentView: View {
@State private var currentNumber: Int
init(currentNumber: Int) {
self.currentNumber = currentNumber
}
var body: some View {
FancyLabelViewControllerRepresentable(currentNumber: self.$currentNumber)
Button("Increment") {
self.currentNumber += 1
}
}
}
struct FancyLabelViewControllerRepresentable: UIViewControllerRepresentable {
typealias UIViewControllerType = FancyLabelViewController
@Binding var currentNumber: Int
init(currentNumber: Binding<Int>) {
self._currentNumber = currentNumber
}
func makeUIViewController(context: Context) -> FancyLabelViewController {
let fancyLabel = FancyLabelViewController(number: self.currentNumber)
fancyLabel.currentNumberInLabel = self.currentNumber
return fancyLabel
}
func updateUIViewController(_ uiViewController: FancyLabelViewController, context: Context) {
uiViewController.currentNumberInLabel = self.currentNumber
}
}
class FancyLabelViewController: UIViewController {
var label = UILabel()
@Binding var currentNumberInLabel: Int
init(number: Int) {
// Error: 'self' used in property access 'currentNumberInLabel' before 'super.init' call
self.currentNumberInLabel = number
// Error: Property 'self.currentNumberInLabel' not initialized at super.init call
super.init(nibName: nil, bundle: nil)
}
required init(coder: NSCoder) {
fatalError("Not implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
label.text = "\(currentNumberInLabel)"
view = label
}
}
我认为你不需要
@Binding var currentNumberInLabel: Int
因为 UIViewControllerRepresentable
已经负责更新 currentNumberInLabel
值,但您还需要更新
label.text = "\(currentNumberInLabel)"
所以我做了类似
的事情class FancyLabelViewController: UIViewController {
var label = UILabel()
var currentNumberInLabel: Int
init(number: Int) {
self.currentNumberInLabel = number
super.init(nibName: nil, bundle: nil)
}
required init(coder: NSCoder) {
fatalError("Not implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
label.text = "\(currentNumberInLabel)"
view = label
}
func updateLabel() {
label.text = "\(currentNumberInLabel)"
}
}
并从 UIViewControllerRepresentable
调用 updateLabel
作为
func updateUIViewController(_ uiViewController: FancyLabelViewController, context: Context) {
uiViewController.currentNumberInLabel = self.currentNumber
uiViewController.updateLabel()
}