使用startUpdatingLocation()和stopUpdatingLocation()激活/停用特定视图中的位



基于stackoverflow中的一些代码示例,我创建了一个定位服务类。定位服务在应用程序启动时立即启动,由系统上部栏中的导航符号指示。我的应用程序只需要特定视图中的定位服务,所以我想在特定事件中激活/停用定位服务。这可以减少能源消耗,提高客户的信心,即只有在需要时才使用定位服务。

首先,我定义了一个类LocationViewModel:

import SwiftUI
import Foundation
import Combine
import CoreLocation
import CoreMotion
class LocationViewModel: NSObject, ObservableObject
{
@Published var userLatitude: Double = 0
@Published var userLongitude: Double = 0

private let locationManager = CLLocationManager()
override init()
{
super.init()

self.locationManager.delegate = self

self.locationManager.startUpdatingLocation()
}

// I tried this to access the startUpdatingLocation() method, but it did not work
func startUpdatingLocation()
{
self.locationManager.startUpdatingLocation()
}

}
extension LocationViewModel: CLLocationManagerDelegate
{
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
guard let location = locations.last else { return }

userLatitude = location.coordinate.latitude
userLongitude = location.coordinate.longitude
}
}

接下来,在作为NavigationView一部分的特定LocationView中,我创建LocationViewModel类的一个实例:

import SwiftUI
struct LocationView : View
{
// some say, that a @StateObject is preferred over @ObservedObject, see:
// https://stackoverflow.com/questions/59620573/handle-swiftui-and-corelocation-with-mvvm-pattern
@ObservedObject var locationViewModel = LocationViewModel()

var body: some View
{
VStack
{
Text("Latitude: (locationViewModel.userLatitude)")
Text("Longitude: (locationViewModel.userLongitude)")
}
.navigationTitle("Location")
.navigationBarTitleDisplayMode(.inline)
}
}

问题:

  1. 为什么在应用程序启动时启动定位服务?override init((方法调用startUpdatingLocation((,但LocationView(定义为NavigationView的一部分(在应用程序启动时不显示。这是NavigationView的效果吗?

  2. 如何从实例外部访问self.locationManager的startUpdatingLocation((方法?有没有任何方法可以直接做到这一点,或者有必要创建一个特定的包装器方法(我已经尝试过了,但没有成功(?LocationViewModel实例不提供任何方法(XCode表示没有完成(。

  3. 当特定视图可见/不可见时,如何启动/停止位置更新(导航符号消失(?我发现的所有代码示例都实现了永久位置更新。

解决方案:

我的错误是试图在视图正文的声明之前调用locationViewModel.locationManager.startUpdatingLocation((方法

.navigationTitle("Simulation")
.navigationBarTitleDisplayMode(.inline)
.onAppear(perform: {locationViewModel.locationManager.startUpdatingLocation()})
.onDisappear(perform: {locationViewModel.locationManager.stopUpdatingLocation()})

最新更新