gpt4 book ai didi

SwiftUI = UIViewControllerRepresentable 通过@Binding 更新文本

转载 作者:行者123 更新时间:2023-12-05 05:07:30 28 4
gpt4 key购买 nike

在 SwiftUI 中,我试图使用一个按钮来实现 UIViewControllerRepresentable 中的文本更改,但可能缺少有关绑定(bind)的关键概念。

在 SwiftUI 中:

struct MainView: View {
@State private var textHere = "Set up text"
var body: some View {
return VStack{
DisplayView(text: $textHere)
Button(action:{
self.textHere = "Button update text"
}) {
HStack {
Text("Change the text by clicking")
.background(Color.white)
}
}
.background(Color.blue)
}
}
}

然后我有一个 UIViewControllerRepresentable:

struct DisplayView: UIViewControllerRepresentable  {
@Binding var text: String

func makeUIViewController(context: UIViewControllerRepresentableContext< DisplayView >) -> UIViewController {
let controller = DisplayViewController()
controller.text = text
return controller
}

func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext< DisplayView >) {
let controller = DisplayViewController()
controller.text = text
controller.updateText()
}
}

我的 View Controller :

class CameraViewController : UIViewController {
var text = "Hello"
var textViewTest = UILabel()

func updateText(){
print("update text " + text)
self.textViewTest = UILabel(frame: CGRect(x: 40.0, y: 120.0, width: 250.0, height: 100.0))
...
self.textViewTest.text = text
}

override func viewDidLoad() {
super.viewDidLoad()
self.textViewTest = UILabel(frame: CGRect(x: 40.0, y: 120.0, width: 250.0, height: 100.0))
...
self.textViewTest.text = text
view.addSubview(self.textViewTest)
}
}

我尝试了 updateText() 函数的一些变体。

数据从按钮点击传递过来:

  • “按钮更新文字”传入UIViewControllerRepresentable的updateUIViewController方法
  • “按钮更新文本”被传递到界面 View Controller
  • “按钮更新文本”被传递到 UIViewController 的 viewDidLoad

但是传递的值不会显示为标签上的更改。

似乎有可能更新是在 ViewController 中进行的,但 SwiftUI View 没有更新?

编辑:

This article向我指出了“包装”UIRepresentable 的方向。这是新版本:

    struct DisplayView: UIViewControllerRepresentable  {
typealias UIViewControllerType = CameraViewController
var text: String?

func makeUIViewController(context: UIViewControllerRepresentableContext< DisplayView >) -> CameraViewController {
print("view called")
return CameraViewController()
}

func updateUIViewController(_ cameraViewController: CameraViewController, context: UIViewControllerRepresentableContext< DisplayView >) {
print("View updated")
cameraViewController.text = text
}
}

并且 ViewController 已经更新:

final class CameraViewController : UIViewController {
var text: String? {
didSet {
updateController()
}
}

private var ccmeraViewController: CameraViewController?

func updateController(){
let textViewTest = UILabel(frame: CGRect(x: 40.0, y: 120.0, width: 250.0, height: 100.0))
guard let text = text else { return }

textViewTest.center = self.view.center
textViewTest.textAlignment = NSTextAlignment.justified
textViewTest.textColor = UIColor.blue
textViewTest.backgroundColor = UIColor.lightGray
textViewTest.text = text
view.addSubview(textViewTest)
}

override func viewDidLoad() {
super.viewDidLoad()
//updateController()
}

一切都很好!我们现在可以正确地将字符串值从 SwiftUI 传递到 ViewController 并更新标签。

但是,当您第一次打开页面时,makeUIViewController 和 updateUIViewController 都会被调用,因此标签的两个实例会出现在彼此之上。

所以最后一步是弄清楚如何只显示一次 UILabel。

更新 3 和部分解决方案

包含解决方案的最小存储库 can be found here .

回答正确,需要添加@Binding。然而,有趣的是,将字符串绑定(bind)到显示标签的 ViewController 会导致 View 中出现标签的两个实例。

通过将 UILabel 从 SwiftUI 绑定(bind)到 UIViewControllerRepresentable 解决了这个问题,但是当字符串值更新时标签会改变位置。

我不清楚:a) 为什么 UIViewControllerRepresentable 收到两个更新 View 的请求或 b) 为什么 UILabel 改变位置。

同样,从 SwiftUI 绑定(bind)一个 UILabel 也没有多大意义。这本来是为了测试嵌入 ViewController 并使用它们来显示标签,这并不是您真正想要做的,但为什么会发生这些问题并没有多大意义。

最佳答案

您可能需要像这样绑定(bind) text:

 struct DisplayView: UIViewControllerRepresentable  {
typealias UIViewControllerType = CameraViewController
@Binding var text: String
....

关于SwiftUI = UIViewControllerRepresentable 通过@Binding 更新文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59054520/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com