使用ObservableObject

使用ObservableObject

我正在尝试学习与SwiftUI结合,并且正在努力使用ObservableObject(以前是BindableObject)更新我的 View (从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数组绑定(bind)到 View ,使得实际上每次刷新都会添加一个新点?

最佳答案

为了确保您的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)
    }
}

关于swift - 如何使用ObservableObject更新UIViewRepresentable,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57478134/

10-08 23:49