我正在努力学习如何与SwiftUI结合,并且我正在挣扎如何用ObservableObject (以前的BindableObject)更新我的视图(从UIKit)。问题是,显然,一旦updateUIView对象发送已更改的通知,@Published方法就不会触发。
class DataSource: ObservableObject {
@Published var locationCoordinates = [CLLocationCoordinate2D]()
var value: Int = 0
init() {
Timer.scheduledTimer(withTimeInterval: 3, repeats: true) { timer in
self.value += 1
self.locationCoordinates.append(CLLocationCoordinate2D(latitude: 52, longitude: 16+0.1*Double(self.value)))
}
}
}
struct MyView: UIViewRepresentable {
@ObservedObject var dataSource = DataSource()
func makeUIView(context: Context) -> MKMapView {
MKMapView(frame: .zero)
}
func updateUIView(_ view: MKMapView, context: Context) {
let newestCoordinate = dataSource.locationCoordinates.last ?? CLLocationCoordinate2D(latitude: 52, longitude: 16)
let annotation = MKPointAnnotation()
annotation.coordinate = newestCoordinate
annotation.title = "Test #\(dataSource.value)"
view.addAnnotation(annotation)
}
}如何将该locationCoordinates数组绑定到视图,即每次刷新时都会添加一个新的点?
发布于 2019-08-13 13:48:49
为了确保您的ObservedObject不会多次被创建(您只需要它的一个副本),您可以将它放在UIViewRepresentable之外
import SwiftUI
import MapKit
struct ContentView: View {
@ObservedObject var dataSource = DataSource()
var body: some View {
MyView(locationCoordinates: dataSource.locationCoordinates, value: dataSource.value)
}
}
class DataSource: ObservableObject {
@Published var locationCoordinates = [CLLocationCoordinate2D]()
var value: Int = 0
init() {
Timer.scheduledTimer(withTimeInterval: 3, repeats: true) { timer in
self.value += 1
self.locationCoordinates.append(CLLocationCoordinate2D(latitude: 52, longitude: 16+0.1*Double(self.value)))
}
}
}
struct MyView: UIViewRepresentable {
var locationCoordinates: [CLLocationCoordinate2D]
var value: Int
func makeUIView(context: Context) -> MKMapView {
MKMapView(frame: .zero)
}
func updateUIView(_ view: MKMapView, context: Context) {
print("I am being called!")
let newestCoordinate = locationCoordinates.last ?? CLLocationCoordinate2D(latitude: 52, longitude: 16)
let annotation = MKPointAnnotation()
annotation.coordinate = newestCoordinate
annotation.title = "Test #\(value)"
view.addAnnotation(annotation)
}
}发布于 2019-11-12 21:30:40
这个解决方案适用于我,但适用于EnvironmentObject https://gist.github.com/svanimpe/152e6539cd371a9ae0cfee42b374d7c4。
发布于 2021-11-27 12:34:04
我将提供一个通用的解决方案,任何UI/NS视图表示使用组合。我的方法有性能上的好处。
注意--对环境对象非常有用。
struct swiftUIView : View {
@EnvironmentObject var env : yourViewModel
...
...
UIViewRep(wm : env)
}
struct UIViewRep : UIViewRepresentable {
var wm : yourViewModel
func makeUIView {
let yv = yourView()
yv.addViewModel(wm)
return yv
}}
class yourView : UIView {
var viewModel : yourViewModel?
var cancellable = Set<AnyCancellable>()
...
...
func addViewModel( _ wm : yourViewModel) {
self.viewModel = wm
self.viewModel?.desiredProperty
.sink(receiveValue: { [unowned self] w in
print("Make changes with ", w)
}).store(in: &cancellable)
}
}https://stackoverflow.com/questions/57478134
复制相似问题