gpt4 book ai didi

swift - 如何在SwiftUI中使用onReceive从ObservedObject获取数据?

转载 作者:行者123 更新时间:2023-12-04 19:25:39 24 4
gpt4 key购买 nike

在我的SwiftUI应用中,每次值更改时,我都需要从ObservedObject获取数据。我知道我们可以使用.onReceive来做到这一点?我不太了解Apple的文档。我不知道该怎么做。
我的代码:

import SwiftUI
import CoreLocation

struct Compass: View {

@StateObject var location = LocationManager()
@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: -CGFloat(self.angle.degreesToRadians)))
.onReceive(location, perform: {
withAnimation(.easeInOut(duration: 1.0)) {
self.angle = self.location.heading
}
})

Text(String(self.location.heading.degreesToRadians))
.font(.system(size: 20))
.fontWeight(.light)
.padding(.top, 15)
}
}
}

struct RotationEffect: GeometryEffect {
var angle: CGFloat

var animatableData: CGFloat {
get { angle }
set { angle = newValue }
}

func effectValue(size: CGSize) -> ProjectionTransform {
return ProjectionTransform(
CGAffineTransform(translationX: -150, y: -150)
.concatenating(CGAffineTransform(rotationAngle: angle))
.concatenating(CGAffineTransform(translationX: 150, y: 150))
)
}
}
在LocationManager类中,我有一个标题Published变量,这是我要检查的变量。
每当我的箭头移动时,每次更改航向的值时都需要获取数据以创建动画。对于某些理由,我需要使用CGAffineTransform。

最佳答案

首先,您需要请求HeadingProvider开始更新标题。您需要收听objectWillChange通知,该闭包具有一个参数,该参数是在ObservableObject上设置的新值。
我对您的指南针做了一些改动:

struct Compass: View {

@StateObject 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()。

关于swift - 如何在SwiftUI中使用onReceive从ObservedObject获取数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58103186/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com