[英]I can not change the value with .onAppear(), .onTapGesture() function and with a NavigationLink in SwiftUI
[英].onAppear() function not working with NavigationLink
我正在研究一個收集實時位置數據並將其存儲在數據庫中的項目(使用 google firebase)。 我對 Swift 比較陌生,但已經編碼了大約 2 年。 我創建了一個基本的 HomePage UI 和一個 MapView UI,使用導航鏈接從一個頁面移動到另一個頁面。 MapViewModel 類是用於從用戶那里收集位置數據的類。 我正在嘗試使用 .onAppear 調用 MapViewModel 類的方法。 盡管當我運行程序時,該函數沒有被調用,並且“內部”也沒有打印在終端上。 我是否遺漏了有關 .onAppear 和導航鏈接如何工作的內容? 請讓我知道當視圖切換到 MapView 時調用該函數的最佳解決方案是什么。
import SwiftUI
import MapKit
struct HomePage: View {
@State private var viewModel = MapViewModel()
var body: some View {
NavigationView {
ZStack {
LinearGradient(
gradient: Gradient(colors: [.blue, Color(red:0.18, green: 0.79, blue: 0.91, opacity: 1.0)]),
startPoint: .topLeading,
endPoint: .bottomTrailing)
.edgesIgnoringSafeArea(.all)
NavigationLink {
MapView()
}
label: {
ZStack {
Circle()
.trim(from: 0.5)
.frame(width: 450, height: 450)
.foregroundColor(Color(red: 1.0, green: 0.89, blue: 0.36, opacity: 1.0))
Text("Navigate")
.foregroundColor(.white)
.font(.system(size:32, weight: .bold, design: .default))
.padding(.bottom, 280)
}
.position(x: 195, y: 900)
.ignoresSafeArea(.all)
}
}
}
}
}
struct MapView: View {
@State private var viewModel = MapViewModel()
var body: some View {
Map(coordinateRegion: $viewModel.region, showsUserLocation: true)
.ignoresSafeArea()
.accentColor(Color(.systemPink))
.onAppear {
print("inside")
viewModel.checkIfLocationServiceIsEnabled()
}
}
}
final class MapViewModel : NSObject, ObservableObject, CLLocationManagerDelegate {
@Published var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 33, longitude: -120), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5))
var locationManager: CLLocationManager?
func checkIfLocationServiceIsEnabled() {
if CLLocationManager.locationServicesEnabled() {
locationManager = CLLocationManager()
locationManager!.startUpdatingLocation()
locationManager!.delegate = self
}
else {
print("Print error message")
}
}
func checkLocationAuthorization() {
guard let locationManager = locationManager else { return }
switch locationManager.authorizationStatus {
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
case .restricted:
print("Location restricted")
case .denied:
print("You have denied location permission, go to settings")
case .authorizedAlways, .authorizedWhenInUse:
print("Inside")
if locationManager.location?.coordinate != nil {
region = MKCoordinateRegion(center: locationManager.location!.coordinate, span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5))
}
else {
print("Location not found")
}
@unknown default:
break
}
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
checkLocationAuthorization()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let lastLocation = locations.last!
print(lastLocation)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
HomePage()
}
}
在您的HomePage
視圖中使用@StateObject var viewModel = MapViewModel()
。 將.environmentObject(viewModel)
添加到您的NavigationView
和相應的@EnvironmentObject var viewModel: MapViewModel
in MapView
。 為我工作。
這是我用於測試的代碼,對我有用。
import Foundation
import SwiftUI
import MapKit
struct ContentView: View {
var body: some View {
HomePage()
}
}
struct HomePage: View {
@StateObject var viewModel = MapViewModel() // <-- here
var body: some View {
NavigationView {
ZStack {
LinearGradient(
gradient: Gradient(colors: [.blue, Color(red:0.18, green: 0.79, blue: 0.91, opacity: 1.0)]),
startPoint: .topLeading,
endPoint: .bottomTrailing)
.edgesIgnoringSafeArea(.all)
NavigationLink {
MapView()
}
label: {
ZStack {
Circle()
.trim(from: 0.5)
.frame(width: 450, height: 450)
.foregroundColor(Color(red: 1.0, green: 0.89, blue: 0.36, opacity: 1.0))
Text("Navigate")
.foregroundColor(.white)
.font(.system(size:32, weight: .bold, design: .default))
.padding(.bottom, 280)
}
.position(x: 195, y: 900)
.ignoresSafeArea(.all)
}
}
}.environmentObject(viewModel) // <-- here
}
}
struct MapView: View {
@EnvironmentObject var viewModel: MapViewModel // <-- here
var body: some View {
Map(coordinateRegion: $viewModel.region, showsUserLocation: true)
.ignoresSafeArea()
.accentColor(Color(.systemPink))
.onAppear {
print("\n----> in onAppear \n")
viewModel.checkIfLocationServiceIsEnabled()
}
}
}
final class MapViewModel : NSObject, ObservableObject, CLLocationManagerDelegate {
@Published var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 33, longitude: -120), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5))
func checkIfLocationServiceIsEnabled() {
print("\n----> in checkLocationAuthorization")
}
}
如果這不適用於您的系統,請嘗試以下操作:
struct MapView: View {
@EnvironmentObject var viewModel: MapViewModel
var body: some View {
VStack { // <-- here
Map(coordinateRegion: $viewModel.region, showsUserLocation: true)
.ignoresSafeArea()
.accentColor(Color(.systemPink))
}
.onAppear {
print("\n----> in onAppear \n")
viewModel.checkIfLocationServiceIsEnabled()
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.