在SwiftUI中,我尝试使用一个按钮来实现UIViewControllerRepresentable中的文本更改,但可能缺少一个关于绑定的关键概念。
在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()
}
}我的ViewController:
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()函数中的一些变体。
数据是通过单击按钮传递的:
但是传递的值不会显示为标签上的更改。
更新可能是在ViewController中进行的,但是SwiftUI视图没有更新吗?
编辑:
这篇文章向我指出了“包装”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和部分解决方案
使用解决方案可以在这里找到的最小存储库。
答案是正确的,您需要添加@Binding。然而,有趣的是,将一个字符串绑定到一个显示标签的ViewController会导致在视图中出现两个标签实例。
通过将UILabel从SwiftUI绑定到UIViewControllerRepresentable解决了这个问题,但是在更新字符串值时标签会更改位置。
我不清楚:( a)为什么UIViewControllerRepresentable收到两个更新视图的请求;或者( b)为什么UILabel更改位置。
同样,将UILabel绑定到SwiftUI中也没有多大意义。这是对嵌入ViewControllers的测试,使用它们来显示标签并不是您真正想要做的事情,但是这些问题发生的原因并没有多大意义。
发布于 2019-11-26 18:01:07
您可能需要像这样绑定text:
struct DisplayView: UIViewControllerRepresentable {
typealias UIViewControllerType = CameraViewController
@Binding var text: String
....https://stackoverflow.com/questions/59054520
复制相似问题