有条件地分配 UIViewControllerRepresentable 类型的视图无法在状态更改时呈现更改
Conditionally assigning a view of type UIViewControllerRepresentable fails to render changes when State is changed
按“FIRST”或“SECOND”文本视图应更改状态 selection
并相应地更新 selectedView
。虽然调试器显示按下“FIRST”或“SECOND”会导致 body
重新计算并正确分配 selectedView
,但屏幕永远不会更新以显示正确的视图。相反,屏幕仅显示与 selection
的初始化状态相对应的视图,并停留在该视图上。
import UIKit
import SwiftUI
struct TestView: View {
@State private var selection: Int = 1
var body: some View {
let firstView = TestRepresentable(string: "First View")
let secondView = TestRepresentable(string: "Second View")
let selectedView = selection == 1 ? firstView : secondView
let finalView = VStack {
HStack {
Text("FIRST").onTapGesture { self.selection = 1 }.padding()
Text("SECOND").onTapGesture { self.selection = 2 }.padding()
}
selectedView
}
return finalView
}
}
struct TestRepresentable: UIViewControllerRepresentable {
let string: String
func makeUIViewController(context: Context) -> TestVC {
return TestVC().create(string)
}
func updateUIViewController(_ uiViewController: TestVC, context: Context) {
//...
}
func makeCoordinator() -> Coordinator {
Coordinator(testRepresentable: self)
}
class Coordinator: NSObject {
var testRepresentable: TestRepresentable
init(testRepresentable: TestRepresentable) {
self.testRepresentable = testRepresentable
}
}
}
class TestVC: UIViewController {
private let label = UILabel()
override func loadView() {
super.loadView()
view.addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
label.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
label.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
label.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
label.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
}
func create(_ string: String) -> TestVC {
label.text = string
return self
}
}
当我将 TestRepresentable(string: "First View")
与 Text("First View")
交换(并对“第二视图”执行相同操作)时,屏幕会正确更新。关于我的 UIViewController 或 UIViewControllerRepresentable 实现的一些事情阻止了我的 SwiftUI 视图中的更改呈现在屏幕上。为什么不更改状态变量 selection
呈现正确的 selectedView
?
这不是 SwiftUI 编码(所以 body 无法正确跟踪状态变化),这里是代码的固定部分(用 Xcode 13 / iOS 15 测试)
var body: some View {
VStack {
HStack {
Text("FIRST").onTapGesture { self.selection = 1 }.padding()
Text("SECOND").onTapGesture { self.selection = 2 }.padding()
}
if selection == 1 {
TestRepresentable(string: "First View")
} else {
TestRepresentable(string: "Second View")
}
}
}
按“FIRST”或“SECOND”文本视图应更改状态 selection
并相应地更新 selectedView
。虽然调试器显示按下“FIRST”或“SECOND”会导致 body
重新计算并正确分配 selectedView
,但屏幕永远不会更新以显示正确的视图。相反,屏幕仅显示与 selection
的初始化状态相对应的视图,并停留在该视图上。
import UIKit
import SwiftUI
struct TestView: View {
@State private var selection: Int = 1
var body: some View {
let firstView = TestRepresentable(string: "First View")
let secondView = TestRepresentable(string: "Second View")
let selectedView = selection == 1 ? firstView : secondView
let finalView = VStack {
HStack {
Text("FIRST").onTapGesture { self.selection = 1 }.padding()
Text("SECOND").onTapGesture { self.selection = 2 }.padding()
}
selectedView
}
return finalView
}
}
struct TestRepresentable: UIViewControllerRepresentable {
let string: String
func makeUIViewController(context: Context) -> TestVC {
return TestVC().create(string)
}
func updateUIViewController(_ uiViewController: TestVC, context: Context) {
//...
}
func makeCoordinator() -> Coordinator {
Coordinator(testRepresentable: self)
}
class Coordinator: NSObject {
var testRepresentable: TestRepresentable
init(testRepresentable: TestRepresentable) {
self.testRepresentable = testRepresentable
}
}
}
class TestVC: UIViewController {
private let label = UILabel()
override func loadView() {
super.loadView()
view.addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
label.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
label.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
label.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
label.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
}
func create(_ string: String) -> TestVC {
label.text = string
return self
}
}
当我将 TestRepresentable(string: "First View")
与 Text("First View")
交换(并对“第二视图”执行相同操作)时,屏幕会正确更新。关于我的 UIViewController 或 UIViewControllerRepresentable 实现的一些事情阻止了我的 SwiftUI 视图中的更改呈现在屏幕上。为什么不更改状态变量 selection
呈现正确的 selectedView
?
这不是 SwiftUI 编码(所以 body 无法正确跟踪状态变化),这里是代码的固定部分(用 Xcode 13 / iOS 15 测试)
var body: some View {
VStack {
HStack {
Text("FIRST").onTapGesture { self.selection = 1 }.padding()
Text("SECOND").onTapGesture { self.selection = 2 }.padding()
}
if selection == 1 {
TestRepresentable(string: "First View")
} else {
TestRepresentable(string: "Second View")
}
}
}