ios - 尝试在内容视图中使用 SwiftUI 获取用户位置但显示 nil
问题描述
我是一个初学者,试图从 LocationManager 获取纬度和经度,并使用 SwiftUI 在 ContentView 中显示它,但结果显示为零。但是控制台打印来自 LocationManager 类的数据。不显示内容视图中的纬度和经度。任何人都可以帮忙吗?(Xcode 11)
这是 LocationManager 类
import Foundation
import CoreLocation
import Combine
class LocationManager: NSObject,CLLocationManagerDelegate, ObservableObject {
private let manager: CLLocationManager
var willChange = PassthroughSubject<LocationManager, Never>()
var getLat: String = ""
var getLon: String = ""
var lastKnownLocation: CLLocation? {
willSet {
willChange.send(self)
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .denied {
print("denied")
}
else{
print("athorized")
manager.requestLocation()
}
}
func start() {
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
}
init(manager: CLLocationManager = CLLocationManager()) {
self.manager = manager
super.init()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error.localizedDescription)
}
func startUpdating() {
self.manager.delegate = self
self.manager.requestWhenInUseAuthorization()
self.manager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//print(locations)
lastKnownLocation = locations.last
getLat = "\(locations.last!.coordinate.latitude)"
getLon = "\(locations.last!.coordinate.longitude)"
showLocation()
}
func showLocation() {
print("from showLocation")
print("Latitude: \(getLat)")
print("Longitude: \(getLon)")
}
}
这是显示 LocationManager 类的纬度和经度的控制台
这是内容视图
import SwiftUI
import CoreLocation
struct ContentView: View {
@State var managerDelegate = LocationManager()
@State var manager = CLLocationManager()
@ObservedObject var location = LocationManager()
var lat: String {
return "\(location.lastKnownLocation?.coordinate.latitude ?? 0.0)"
}
var lon: String {
return "\(location.lastKnownLocation?.coordinate.longitude ?? 0.0)"
}
init() {
self.manager.delegate = self.managerDelegate
do {
try self.manager.requestAlwaysAuthorization()
}
catch {
print(error.localizedDescription)
self.manager.requestAlwaysAuthorization()
}
}
var body: some View {
VStack {
Text("Hello, World")
Text("Latitude: \(lat)")
Text("Longitude: \(lon)")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
解决方案
好吧,我发现自己有时间阅读您的代码,并且我为您提供了解决方案。
首先,您需要在内部将委托设置为您正在观察的变量ContentView.init()
:
self.manager.delegate = self.location
紧接着,您将需要调用startUpdating()
您在中定义的函数LocationManager
:
self.location.startUpdating()
最后,您可能想要删除您的will-change
实现并选择更简单的:
@Published var lastKnownLocation: CLLocation?
已发布的包装器将自动为您触发对象更改。
重构
现在,如果您愿意,还可以将 init 语句减少到一行:
init() {
self.location.startUpdating()
}
这意味着您可以自由删除几个属性:
`@State var managerDelegate = LocationManager()`
`@State var manager = CLLocationManager()`
TLDR; 这是代码的简化版本:
内容视图
import SwiftUI
struct ContentView: View {
@ObservedObject var location = LocationManager()
var lat: String {
return "\(location.lastKnownLocation?.coordinate.latitude ?? 0.0)"
}
var lon: String {
return "\(location.lastKnownLocation?.coordinate.longitude ?? 0.0)"
}
init() {
self.location.startUpdating()
}
var body: some View {
VStack {
Text("Location breakdown")
Text("Latitude: \(lat)")
Text("Longitude: \(lon)")
}
.padding()
.padding()
.background(Color.white)
.cornerRadius(10)
.shadow(radius: 10)
}
}
位置管理器
import Foundation
import CoreLocation
class LocationManager: NSObject, CLLocationManagerDelegate, ObservableObject {
private let manager = CLLocationManager()
@Published var lastKnownLocation: CLLocation?
func startUpdating() {
self.manager.delegate = self
self.manager.requestWhenInUseAuthorization()
self.manager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
lastKnownLocation = locations.last
}
}
推荐阅读
- javascript - 表格详细信息的道具
- r - 为什么布冯的针法估计 pi 没有产生期望值?
- ruby-on-rails - 以不同的方式将红宝石中的数字向上或向下舍入到最接近的 10 / 100 / 1000
- php - 如何在codeigniter中用一列检查两个值
- android - 当 launchMode 是单任务时,从 MainActivity 中的另一个应用程序接收 action_send 的问题
- c# - 从对象的 Json 字符串中以 Xamarin 形式显示新闻文章列表
- mysql - 通过数据透视表连接两个表并在mysql中检索特定结果
- testing - 测试“-timeout 0”未反映在执行中
- angular - PrimeNg 条形图如何显示 y 轴的标签
- interface - 如何在具有 SV 接口的块上使用 generate