SwiftUI中MapKit能否从Firestore读取经纬度动态设置地图坐标
解决方案
首先明确:完全可以用Firestore读取的动态坐标设置Map视图,不需要只能用静态值,你遇到的两个问题都有明确的修复方案:
1. 修复BusinessAddressRowViewModel的shared报错
你代码里的public static let shared = BusinessAddressRowViewModel()完全多余,你的整个数据流是由BusinessAddressRepository监听Firestore变更,再由BusinessAddressViewModel自动生成每个地址对应的BusinessAddressRowViewModel实例,根本不需要单例,直接删除这一行即可解决参数缺失的报错。
2. 修复BusinessMapView不能用ViewModel坐标的问题
你遇到的「属性初始化不能访问其他实例属性」是Swift语法限制,有两种成熟的方案解决:
方案一:自定义视图初始化方法给@State赋初始值
直接在视图的init方法中,用传入的ViewModel坐标给region设置初始值,代码如下:
struct BusinessMapView: View { @ObservedObject var businessAddressRowViewModel: BusinessAddressRowViewModel @State private var region: MKCoordinateRegion // 自定义初始化方法 init(viewModel: BusinessAddressRowViewModel) { self.businessAddressRowViewModel = viewModel // 下划线访问@State的内部存储值,完成初始化 self._region = State(initialValue: MKCoordinateRegion( center: CLLocationCoordinate2D( latitude: viewModel.businessAddress.latitude, longitude: viewModel.businessAddress.longitude ), span: MKCoordinateSpan(latitudeDelta: 5.0, longitudeDelta: 5.0) )) } var body: some View { Map(coordinateRegion: $region) } }
方案二:监听地址变更自动更新地图(更适合动态数据场景)
如果你的业务地址可能会在Firestore中更新,建议用onReceive监听ViewModel的@Published属性变更,自动同步地图区域:
struct BusinessMapView: View { @ObservedObject var businessAddressRowViewModel: BusinessAddressRowViewModel @State private var region = MKCoordinateRegion( center: CLLocationCoordinate2D(latitude: 0, longitude: 0), span: MKCoordinateSpan(latitudeDelta: 5.0, longitudeDelta: 5.0) ) var body: some View { Map(coordinateRegion: $region) .onReceive(businessAddressRowViewModel.$businessAddress) { newAddress in // 地址变更时自动更新地图区域 region.center = CLLocationCoordinate2D( latitude: newAddress.latitude, longitude: newAddress.longitude ) } } }
调用方式
你在BusinessAddressView的列表中,点击某一行地址跳转地图,或者在地址行中嵌入小地图时,直接把对应位置的BusinessAddressRowViewModel实例传入即可:
// 列表中跳转示例 NavigationLink { BusinessMapView(viewModel: businessAddressRowViewModels[indexPath.row]) } label: { BusinessAddressRow(viewModel: businessAddressRowViewModels[indexPath.row]) }
内容的提问来源于stack exchange,提问作者jonthornham
相关产品推荐
相关产品推荐

