1

按“FIRST”或“SECOND”文本视图应更改状态selectionselectedView相应更新。虽然调试器显示按下“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 视图中的更改在屏幕上呈现。为什么对 State 变量的更改不selection呈现正确的selectedView

4

1 回答 1

1

它只是不是 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")
        }
    }
}
于 2021-12-09T19:22:37.373 回答