swift 第一次加载时,视图具有空值,但记录值

rvpgvaaj  于 2023-03-16  发布在  Swift
关注(0)|答案(1)|浏览(112)

我的主视图ContentView使用LocationManager@StateObject。我的主视图上有一个onChange修饰符,它等待位置的更改。当我最初加载应用时,我在locationManager中看到我的日志语句显示在控制台中:
Current country code: US
但是模态视图显示为空:“欢迎光临!”
如果我手动将模拟器中的位置更改为其他位置,如加拿大,我将看到日志语句Current country code: CA,然后模态视图将正确弹出““Welcome to Canada!”为什么第一次没有显示在我的视图中?

国家.json

[
     {
        "display_name": "United States of America",
        "searchable_names": [
            "united states of america",
            "us",
            "usa"
        ],
        "image": "united-states-of-america",
        "id": 204,
        "iso": "US"
    },
    {
        "display_name": "Canada",
        "searchable_names": [
            "Canada",
            "ca"
        ],
        "image": "canada",
        "id": 205,
        "iso": "CA"
    }
]

代码

struct ContentView: View {
    @State private var isPresented = false
    @Binding var countries: [Country];
    @State var modalCountry: Country?
    @StateObject var locationManager = LocationManager()

    var body: some View {
        VStack {
            //
        }
        .onChange(of: locationManager.countryCode) { country in
            self.isPresented = true                              
         }
        .sheet(isPresented: $isPresented) {
            ModalView(countryModal: self.modalCountry)
        }
    }
}

struct ModalView: View {
    @State var countryModal: Country?
    @Environment(\.presentationMode) var presentationMode
    
    var body: some View {
        VStack {
            Text("Looks like you're in \(countryModal?.display_name ?? "") !")
                .bold()
            Button("Show Me") {
                
            }
            Button("Dismiss") {
                presentationMode.wrappedValue.dismiss()
            }
        }
        .padding()
    }
}

class LocationManager: NSObject, CLLocationManagerDelegate, ObservableObject {
    let locationManager = CLLocationManager()
    @Published var countryCode: Country?
    
    override init() {
        super.init()
        locationManager.delegate = self
        locationManager.distanceFilter = 500 // Only update when user moves 500 meters
        locationManager.desiredAccuracy = kCLLocationAccuracyBest // Highest accuracy possible
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        // Handle location updates here
        guard let currentLocation = locations.last else { return  }
        let geocoder = CLGeocoder()
        geocoder.reverseGeocodeLocation(currentLocation) { (placemarks, error) in
            guard let placemark = placemarks?.first, let countryCode = placemark.isoCountryCode else { return }
            print("Current country code: \(countryCode)")
            self.countryCode = countries.first(where: { $0.iso == countryCode }) ?? nil
        }

    }
fykwrbwg

fykwrbwg1#

试试这个方法,使用.sheet(item:...)并在.onChange(...)中更新modalCountry,对我很有效:

struct ContentView: View {
    @Binding var countries: [Country]
    @State var modalCountry: Country?
    @StateObject var locationManager = LocationManager()
    
    var body: some View {
        VStack {
            Text(locationManager.countryCode?.display_name ?? "no data")
        }
        .onChange(of: locationManager.countryCode) { country in
            modalCountry = country  // <-- here
        }
        .sheet(item: $modalCountry) { country in  // <-- here
            ModalView(countryModal: country)
        }
    }
}

相关问题