添加MapUserTrackingMode引发SwiftUI视图初始化错误问题
解决SwiftUI中LocationInfoView的初始化错误
这两个错误和添加MapUserTrackingMode没有直接关联,本质是**@State属性的初始化方式不符合Swift结构体初始化规则**:
- Swift要求结构体的所有存储属性必须在
self可用之前完成初始化,你当前在init里先赋值self.location,再用self.location初始化mapRegion,此时self还未完全初始化,编译器判定self.location被提前使用。 - 直接给
@State属性赋值self.location = location不是正确的初始化方式,@State属性需要通过其底层的State结构体来初始化。
解决方案1:正确初始化@State底层存储
修改init方法,直接初始化@State对应的下划线前缀属性,同时避免依赖未完全初始化的self:
struct LocationInfoView: View { @State var location: CLLocationCoordinate2D @State private var mapRegion: MKCoordinateRegion @State private var trackingMode = MapUserTrackingMode.follow let markers: [Marker] init(location: CLLocationCoordinate2D) { // 初始化@State的底层存储 _location = State(initialValue: location) // 用传入的参数直接创建区域,不依赖self.location let initialRegion = MKCoordinateRegion(center: location, span: MKCoordinateSpan(latitudeDelta: 0.00625, longitudeDelta: 0.00625)) _mapRegion = State(initialValue: initialRegion) markers = [Marker(location: MapPin(coordinate: location))] } var body: some View { Map( coordinateRegion: $mapRegion, showsUserLocation: true, userTrackingMode: $trackingMode, annotationItems: markers) { marker in marker.location } .edgesIgnoringSafeArea(.bottom) } } struct Marker: Identifiable { let id = UUID() var location: MapPin }
解决方案2:简化状态设计(如果location不需要修改)
如果location只是初始化参数,不需要作为可修改的状态,直接去掉@State修饰,初始化逻辑会更简洁:
struct LocationInfoView: View { let location: CLLocationCoordinate2D // 移除@State @State private var mapRegion: MKCoordinateRegion @State private var trackingMode = MapUserTrackingMode.follow let markers: [Marker] init(location: CLLocationCoordinate2D) { self.location = location mapRegion = MKCoordinateRegion(center: location, span: MKCoordinateSpan(latitudeDelta: 0.00625, longitudeDelta: 0.00625)) markers = [Marker(location: MapPin(coordinate: location))] } var body: some View { Map( coordinateRegion: $mapRegion, showsUserLocation: true, userTrackingMode: $trackingMode, annotationItems: markers) { marker in marker.location } .edgesIgnoringSafeArea(.bottom) } } struct Marker: Identifiable { let id = UUID() var location: MapPin }
内容的提问来源于stack exchange,提问作者HarryMoy
相关产品推荐
相关产品推荐

