如何在swiftUI中显示高性能的CoreLocation航向度?

在我的指南针应用程序中,我显示了航向,但性能不高:当我快速转动设备时,不会显示所有度数。我搜索的性能与Apple的natif罗盘应用程序相同。

例如,当角度通过359到0度时,向notif用户发出振动。但是有时振动不会出现。

如何在swiftUI中显示高性能的CoreLocation航向度?

我的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
}

可能是因为我还计算了纬度+经度+海拔+位置...?还是因为我在角度上进行了很多演算以获得没有零分数的值?我不知道。

a212346 回答:如何在swiftUI中显示高性能的CoreLocation航向度?

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/2837127.html

大家都在问