SwiftUI не обновляет мой пользовательский UIView с UIViewRepresentable & ObservableObject - PullRequest
0 голосов
/ 28 сентября 2019
  1. создать простой ARClass: ObservableObject с @Published var name: String
  2. создать собственный ARView: UIView получил ARClass в качестве параметра и нарисовать текст из ARClass.name в центре
  3. создатьUIViewRepresentable

, а затем использовать в SwuftUI View с использованием ARClass (color: .red, name: "Test Text") в качестве объекта среды в SceneDelegate

class ARClass: ObservableObject {
@Published var bg: UIColor
@Published var name: String

init(color: UIColor, name: String) {
    self.bg = color
    self.name = name
}

}

struct ARViewX: UIViewRepresentable {
var ar: ARClass
var frame: CGRect

func updateUIView(_ uiView: ARView, context: Context) {
    uiView.frame = frame
    uiView.ar = ar
    uiView.setNeedsDisplay()
}
func makeUIView(context: Context) -> ARView {
    ARView(ar: ar, frame: frame)
}

}

struct ContentView: View {
@EnvironmentObject var ar: ARClass
var body: some View {
    GeometryReader { g in
        VStack {
            Spacer()
                ARViewX(ar: self.ar, frame: CGRect(origin: .zero, size: .init(width: g.size.width, height: g.size.height/3)))
                .padding()
            Spacer()
            Text(self.ar.name)
            Divider()
            TextField("Name", text: self.$ar.name)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()
            Spacer()
        }
    }
}

}

Когда я редактировал TextField, все тело обновляется, кроме UIViewRepresentable, оно всегда сбрасывает переменную name в ее начальное значение.

1 Ответ

0 голосов
/ 28 сентября 2019

Через несколько часов, наконец, я знаю, что updateUIView (_ uiView: ARView, context: Context) в UIViewRepresentable никогда не вызывается, поэтому я изменяю ARClass & UIViewRepresentable следующим образом

class ARClass: ObservableObject {
@Published var bg: UIColor
@Published var name: String {
    didSet {
        if let onNameChange = onNameChange {
            onNameChange()
        }
    }
}
var onNameChange: (()->Void)?
init(color: UIColor, name: String) {
    self.bg = color
    self.name = name
}

}

func updateUIView(_ uiView: ARView, context: Context) {
    uiView.frame = frame
    ar.onNameChange = {
        uiView.setNeedsDisplay()
    }
}
...