swift - SwfitUI navigationBarItems 两次调用位置权限
问题描述
我在 下创建了一个按钮navigationBarItems
,这个按钮会打开一个新sheet
的 ,新的工作表会弹出一个窗口询问用户位置。但是,在新工作表中,CLLocationManager() 被调用了两次,定位权限弹窗会在几秒后消失。当您创建一个常规按钮时,位置弹出窗口将一直停留在那里,直到您选择其中一个选项,并且 CLLocationManager() 只会被调用一次。
代码
ContentView.swift
import SwiftUI
struct ContentView: View {
@State var show = false
@State var showEditPage = false
var body: some View {
NavigationView {
List {
Text("Text")
Button("Location button") {
print("Location button tapped")
self.show.toggle()
}.sheet(isPresented: $show) {
NewPage()
}
}
.navigationBarItems(
trailing:
VStack {
Button(action: {
print("BarItemButton tapped")
self.showEditPage.toggle()
}) {
//Top right icon
Text("BarItemButton")
}.sheet(isPresented: $showEditPage) {
//Open sheet page
NewPage()
}
}//End of trailing VStack
)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
新页面.swift
import SwiftUI
struct NewPage: View {
@ObservedObject var locationManager = LocationManager()
var body: some View {
Text("New Page")
}
}
struct NewPage_Previews: PreviewProvider {
static var previews: some View {
NewPage()
}
}
LocationManager.swift
import SwiftUI
import Foundation
import CoreLocation
import Combine
class LocationManager: NSObject, ObservableObject {
private let locationManager = CLLocationManager()
let objectWillChange = PassthroughSubject<Void, Never>()
override init() {
super.init()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
print("In LocationManger.swift @initi, this is called")
}
@Published var locationStatus: CLAuthorizationStatus? {
willSet {
objectWillChange.send()
}
}
@Published var lastLocation: CLLocation? {
willSet { objectWillChange.send() }
}
}
extension LocationManager: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
self.locationStatus = status
print("In LocationManger.swift @Func locationManager, Status is updaing")
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
self.lastLocation = location
print("Location is updating")
}
}
GitHub
您可以随意下载该项目以在您的笔记本电脑上试用以查看问题: Github 示例项目
截屏
解决方案
以下是使其在您的代码中工作的可能方法的更改:
1)使LocationManager只有一个
class LocationManager: NSObject, ObservableObject {
static var defaultManager: LocationManager = {
LocationManager()
}()
...
2)使用默认管理器而不是每次 SwiftUI 想要创建/复制视图结构时创建
struct NewPage: View {
@ObservedObject var locationManager = LocationManager.defaultManager
...
推荐阅读
- django - 如何在views.py [Django]中传递可选参数
- amazon-web-services - 与远程服务器进行 SSL 握手期间的 Apache 错误
- react-native - 任务 :app:generateBundledResourcesHashRelease 在构建 relese apk react-native 时失败
- javascript - css - 无法将按钮移动到中心
- c++ - 在 C++ 中用 cin 读取同一行中的多个整数
- php - Symfony 表实体本身也被识别为存储库
- image-processing - 我们能猜出图像最初显示的值吗?
- javascript - 如何将 Github API v4 (graphql) 与 javascript XMLHttpRequest 一起使用
- r - 在 R 中连接两个数据框
- c++ - C++ 警告:对于增量表达式无效 [-Wunused-value]