SwiftUI中ViewModel绑定Map控件出现非法发布变更错误的问题
SwiftUI Map绑定ObservableObject @Published属性触发弹窗关闭错误的解决方案
在Xcode14.0中,将SwiftUI Map的coordinateRegion绑定到ObservableObject的@Published属性时,会触发弹窗关闭相关的错误,使用本地@State变量则无此问题。移除@Published虽能消除错误,但会丢失ViewModel通知视图更新region的能力,以下是可行的解决办法:
方案1:升级Xcode版本
这个问题是Xcode14.0的已知bug,在Xcode14.1及以上版本中已被官方修复,优先建议升级到最新兼容版本。
方案2:手动桥接绑定(适用于无法升级Xcode的场景)
通过本地@State变量作为中间层,实现ViewModel与视图的双向同步,同时避免直接绑定@Published属性引发的错误:
import SwiftUI import MapKit class MM : ObservableObject { @Published var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)) // 模拟位置更新场景 func updateLocation(newCoordinate: CLLocationCoordinate2D) { region = MKCoordinateRegion(center: newCoordinate, span: region.span) } } struct SimpleMap: View { @ObservedObject var mm = MM() @State private var localRegion: MKCoordinateRegion init() { let initialRegion = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)) _localRegion = State(initialValue: initialRegion) } var body: some View { Map(coordinateRegion: $localRegion) // 监听ViewModel的region变化,同步到本地变量 .onChange(of: mm.region) { newRegion in localRegion = newRegion } // 监听本地变量变化,同步回ViewModel .onChange(of: localRegion) { newRegion in mm.region = newRegion } } }
也可以使用自定义绑定直接封装逻辑,代码更简洁:
struct SimpleMap: View { @ObservedObject var mm = MM() var body: some View { Map(coordinateRegion: Binding( get: { mm.region }, set: { mm.region = $0 } )) } }
两种方式都能保留ViewModel的@Published特性,确保位置更新时视图能收到通知,同时避免触发原有的错误。
内容的提问来源于stack exchange,提问作者JohnH
相关产品推荐
相关产品推荐

