gpt4 book ai didi

swift - 使用 MVVM-Pattern 处理 SwiftUI 和 CoreLocation

转载 作者:行者123 更新时间:2023-12-04 21:49:01 24 4
gpt4 key购买 nike

我正在尝试实现 SwiftUI 核心位置 MVVM 模式 .我的 LocationManager因为 Helper 工作正常。但是如何更改我的 LocationViewModel 的属性?我实现了我的 @ObservedObjectLocationManagerLocationViewModel .这是我的问题。

我不知道如何实现它们即时更改的属性。我的 LocationView 中没有任何变化。通过按下按钮,任何事情都可以正常工作。但是LocationViewModel每次更改 LocationManager 时都必须更改那里的属性.

总之,我想显示当前用户的位置。

// Location Manager as Helper

import Foundation
import CoreLocation

class LocationManager: NSObject, ObservableObject {

let locationManager = CLLocationManager()
let geoCoder = CLGeocoder()

@Published var location: CLLocation?
@Published var placemark: CLPlacemark?

override init() {
super.init()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
}

func geoCode(with location: CLLocation) {

geoCoder.reverseGeocodeLocation(location) { (placemark, error) in
if error != nil {
print(error!.localizedDescription)
} else {
self.placemark = placemark?.first
}
}
}
}

extension LocationManager: CLLocationManagerDelegate {

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

DispatchQueue.main.async {
self.location = location
self.geoCode(with: location)
}

}

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
// TODO
}
}

// Location Model

import Foundation
import CoreLocation

struct Location {
var location: CLLocation = CLLocation()
var placemark: CLPlacemark = CLPlacemark()
}
// Location View Model

import SwiftUI
import CoreLocation

class LocationViewModel: ObservableObject {

@ObservedObject var locationManager: LocationManager = LocationManager()

@Published var location: Location

init() {
self.location = Location()
}
}
// Location View

import SwiftUI

struct LocationView: View {

@ObservedObject var locationViewModel: LocationViewModel = LocationViewModel()

var body: some View {
VStack(alignment: .leading) {
Text("Latitude: \(self.locationViewModel.location.location.coordinate.latitude.description)")
Text("Longitude: \(self.locationViewModel.location.location.coordinate.longitude.description)")
}
}
}

struct LocationView_Previews: PreviewProvider {
static var previews: some View {
LocationView()
}
}

更新

现在,我已经设置了我的 map 查看 .

但是我怎么能收到我的 LocationManager的数据? didUpdateLocations方法在 LocationManager 中有效.

我试图做的所有事情都出错了。我想在我的 MapView 上设置区域基于当前用户位置。在 UIKit 中它非常简单,但在 SwiftUI 中它是怪异的。
// Map View

import SwiftUI
import MapKit

struct MapView: UIViewRepresentable {

@ObservedObject var locationManager: LocationManager = LocationManager()

class Coordinator: NSObject, MKMapViewDelegate {

var parent: MapView

init(_ control: MapView) {
self.parent = control
}

}

func makeCoordinator() -> Coordinator {
Coordinator(self)
}

func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView(frame: .zero)
mapView.delegate = context.coordinator
return mapView
}

func updateUIView(_ mapView: MKMapView, context: Context) {
mapView.showsUserLocation = true
}

}

struct MapView_Previews: PreviewProvider {
static var previews: some View {
MapView()
}
}

最佳答案

SwiftUI 2
改用 StateObject在这种情况下

struct LocationView: View {

@StateObject var locationManager: LocationManager = LocationManager()
...
SwiftUI 1
其实 LocationViewModel这里是多余的。作为您的 LocationManagerObservableObject您可以直接在您的 View 中使用它,如下所示:
struct LocationView: View {

@ObservedObject var locationManager: LocationManager = LocationManager()

var body: some View {
VStack(alignment: .leading) {
Text("Latitude: \(locationManager.location.coordinate.latitude.description)")
Text("Longitude: \(locationManager.location.coordinate.longitude.description)")
}
}
}

关于swift - 使用 MVVM-Pattern 处理 SwiftUI 和 CoreLocation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59620573/

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