簡體   English   中英

.onAppear() 函數不適用於 NavigationLink

[英].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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM