在我的指南针应用程序中,我显示了航向,但性能不高:当我快速转动设备时,不会显示所有度数。我搜索的性能与Apple的natif罗盘应用程序相同。
例如,当角度通过359到0度时,向notif用户发出振动。但是有时振动不会出现。
我的LocationProvider类:
import SwiftUI
import CoreLocation
import Combine
public class LocationProvider: NSObject,CLLocationmanagerDelegate,ObservableObject {
private let locationmanager: CLLocationmanager
public let heading = PassthroughSubject<CGFloat,Never>()
@Published var currentHeading: CGFloat {
willSet {
heading.send(newValue)
}
}
@Published var currentCoordinates: Array<CGFloat> {
willSet {
coordinates.send(newValue)
}
}
@Published var currentArea: Array<String> {
willSet {
area.send(newValue)
}
}
@Published var currentAltitude: Double {
willSet {
altitude.send(newValue)
}
}
public override init() {
currentHeading = 0
currentCoordinates = [0,0]
currentArea = ["",""]
currentAltitude = 0
locationmanager = CLLocationmanager()
super.init()
locationmanager.delegate = self
locationmanager.desiredaccuracy = kCLLocationaccuracyBest
locationmanager.startUpdatingHeading()
locationmanager.startUpdatingLocation()
locationmanager.requestWhenInUseAuthorization()
}
public func updateHeading() {
//locationmanager.startUpdatingHeading()
func locationmanager(_ manager: CLLocationmanager,didUpdateHeading newHeading: CLHeading) {
self.currentHeading = CGFloat(newHeading.trueHeading)
}
}
// Get current latitude and longitude
public func locationmanager(_ manager: CLLocationmanager,didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
currentCoordinates[0] = CGFloat(location.coordinate.latitude)
currentCoordinates[1] = CGFloat(location.coordinate.longitude)
getLocation(from: location) { city,administrativeArea,error in
guard let city = city,let administrativeArea = administrativeArea,error == nil else { return }
self.currentArea[0] = city
self.currentArea[1] = administrativeArea
}
self.currentAltitude = round(1 * location.altitude / 1)
}
// Get current location
public func getLocation(from location: CLLocation,completion: @escaping (_ city: String?,_ administrativeArea: String?,_ error: Error?) -> ()) {
CLGeocoder().reverseGeocodeLocation(location) { placemarks,error in
completion(placemarks?.first?.locality,placemarks?.first?.administrativeArea,error)
}
}
}
我的指南针视图:
import SwiftUI
import CoreLocation
struct Compass: View {
var locationmanager = CLLocationmanager()
@ObservedObject var location: LocationProvider = LocationProvider()
@EnvironmentObject var settingsStore: SettingsStore
@State var angle: CGFloat = 0
var body: some View {
VStack {
...
VStack(alignment: .center,spacing: 0) {
Text(String(Double(-self.location.currentHeading + 360).stringWithoutZeroFraction) + "°")
.foregroundColor(.white)
.lineLimit(2)
.linespacing(3)
.multilineTextAlignment(.center)
.font(.system(size: 38))
.onAppear(perform: {
self.location.updateHeading()
})
HStack(alignment: .center,spacing: 4) {
Image("ic_altitude")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 32)
Text(String(self.altitude.stringWithoutZeroFraction) + "m")
.foregroundColor(.white)
.font(.system(size: 18))
.onReceive(self.location.altitude) { altitude in
self.altitude = altitude
}
}
}
}
.frame(width: geometry.size.height * (0.24),height: geometry.size.height * (0.24),alignment: .center)
.padding(15)
.background(Color("PrimaryLight"))
.overlay(Circle().stroke(Color("PrimaryDark"),lineWidth: 3))
.opacity(1.0)
.clipShape(Circle())
.onReceive(self.location.heading) { heading in
self.angle += calculateAngleDifference(heading,self.angle)
}
.rotationEffect(.degrees(-Double(self.angle)))
.animation(.easeinout(duration: 0.2))
}
...
}
}
stringWithoutZeroFraction函数可删除分数:
var stringWithoutZeroFraction: String {
return String(format: "%.0f",self)
}
calculateAngleDifference函数:
func calculateAngleDifference(_ heading: CGFloat,_ angle: CGFloat) -> CGFloat {
return (clampAngle(heading - angle) + 180).truncatingRemainder(dividingBy: 360) - 180
}
可能是因为我还计算了纬度+经度+海拔+位置...?还是因为我在角度上进行了很多演算以获得没有零分数的值?我不知道。