Сначала, по вашему мнению, вам нужно запросить HeadingProvider, чтобы начать обновление заголовка.Вам необходимо прослушать уведомление objectWillChange, у замыкания есть один аргумент, который является новым значением, устанавливаемым в ObservableObject.
Я немного изменил ваш компас:
struct Compass: View {
@ObservedObject var headingProvider = HeadingProvider()
@State private var angle: CGFloat = 0
var body: some View {
VStack {
Image("arrow")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 300, height: 300)
.modifier(RotationEffect(angle: angle))
.onReceive(self.headingProvider.objectWillChange) { newHeading in
withAnimation(.easeInOut(duration: 1.0)) {
self.angle = newHeading
}
}
Text(String("\(angle)"))
.font(.system(size: 20))
.fontWeight(.light)
.padding(.top, 15)
} .onAppear(perform: {
self.headingProvider.updateHeading()
})
}
}
У меня естьнаписал пример HeadingProvider:
public class HeadingProvider: NSObject, ObservableObject {
public let objectWillChange = PassthroughSubject<CGFloat,Never>()
public private(set) var heading: CGFloat = 0 {
willSet {
objectWillChange.send(newValue)
}
}
private let locationManager: CLLocationManager
public override init(){
self.locationManager = CLLocationManager()
super.init()
self.locationManager.delegate = self
}
public func updateHeading() {
locationManager.startUpdatingHeading()
}
}
extension HeadingProvider: CLLocationManagerDelegate {
public func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
DispatchQueue.main.async {
self.heading = CGFloat(newHeading.trueHeading)
}
}
}
Помните, что вам нужно обработать запрос разрешения на чтение местоположения пользователя, и вам нужно вызвать stopUpdatingHeading () в какой-то момент.