微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ViewState 不会随 MapView 改变

如何解决ViewState 不会随 MapView 改变

我目前正在尝试在工作表中显示 Mapview。奇怪的是,MapView 显示在画布中。但是在模拟器中它没有更新视图。有人可以向我解释一下,我做错了什么吗?

这是我的 Mapviewmodel

class Mapviewmodel: ObservableObject {
    
    enum ViewState {
        case Failed
        case loading
        case value([Checkpoint])
    }
    
    @Published var viewState: ViewState = .loading
    @Published var region = MKCoordinateRegion()

    func initMap(name: String,address: String) {
        self.viewState = .loading
        getLocation(from: address) { coordinate in
            if let coordinate = coordinate {
                let checkpoint = Checkpoint(title: name,coordinate: coordinate)
                self.region = MKCoordinateRegion(center: coordinate,span: MKCoordinateSpan(latitudeDelta: 0.1,longitudeDelta: 0.1))
                
                var checkpoints: [Checkpoint] = []
                checkpoints.append(checkpoint)
                
                dispatchQueue.main.async {
                    withAnimation(.easeInOut) {
                        self.viewState = .value(checkpoints)
                        print("Done")
                    }
                }
            } else {
                dispatchQueue.main.async {
                    self.viewState = .Failed
                }
            }
        }
    }
    
    func getLocation(from address: String,completion: @escaping (_ location: CLLocationCoordinate2D?)-> Void) {
        let geocoder = CLGeocoder()
        geocoder.geocodeAddressstring(address) { (placemarks,error) in
            guard let placemarks = placemarks,let location = placemarks.first?.location?.coordinate else {
                completion(nil)
                return
            }
            completion(location)
        }
    }
}

这是我的视图

struct MapView: View {
    
    @Observedobject var mapVM = Mapviewmodel()
    var name: String
    var address: String
    
    var body: some View {
        switch mapVM.viewState {
            case .loading:
                vstack(alignment: .center) {
                    ProgressView()
                }
                .onAppear() {
                    mapVM.initMap(name: name,address: address)
                }
            case .value(let checkpoints):
                vstack {
                    Map(coordinateRegion: $mapVM.region,annotationItems: checkpoints) { item in
                        MapAnnotation(coordinate: item.coordinate) {
                            vstack(spacing: 0) {
                                Image(systemName: "mappin.circle.fill")
                                    .renderingMode(.original)
                                    .font(.title)
                                Text(name)
                                    .font(.caption)
                                    .shadow(color: Color.systemBackground.opacity(0.5),radius: 1)
                                    .frame(minWidth: 0,maxWidth: 150)
                            }
                        }
                    }
                }
            case .Failed:
                Text("Failed")
            }
    }
    
}

这是我在 MainView 中实现 MapView 的方法

vstack(alignment: .center) {
    MapView(name: tickerDetails.name,address: tickerDetails.hqAddress)
       .frame(width: UIScreen.main.bounds.width - 30,height: 220)
       .border(Color.systemGray4,cornerRadius: 10)
       .padding(.leading)
}

最后但并非最不重要的是,这里有两个屏幕截图,它是如何在画布和模拟器中显示的:

enter image description here

预览数据来自本地存储的 JSON 文件。模拟器的数据是从互联网上获取的。但是数据加载正确,因为打印语句是在 Mapviewmodel 中执行的(并且坐标也是正确的)。它只是不使用数据更新视图。

编辑

我在“普通”视图中实现了 MapView,它在那里工作正常。似乎,所呈现的工作表无法与视图状态一起使用...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。