SwiftUI地图视图初始化报错:self变量未初始化问题求助
SwiftUI地图标注初始化错误修复
我正在开发一款在地图上显示溜冰场的App,参考了Hacking with Swift的Map View标注教程,当前尝试添加自定义标注(暂使用City类)时,在init函数中出现两个错误:
Variable 'self.iceRink' used before being initializedVariable 'self.region' used before being initialized
完整错误代码
import SwiftUI import CoreLocation import MapKit struct IceRink: Identifiable { let id = UUID() let name: String let lat: Double let lng: Double } struct City: Identifiable { let id = UUID() let name: String let coordinate: CLLocationCoordinate2D } struct IceRinkView: View { @State private var iceRink: IceRink @State private var region: MKCoordinateRegion private let annotations: [City] init(iceRink: IceRink) { self.iceRink = iceRink region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: iceRink.lat, longitude: iceRink.lng), span: MKCoordinateSpan(latitudeDelta: 10, longitudeDelta: 10)) annotations = [ City(name: "London", coordinate: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275)), City(name: "Paris", coordinate: CLLocationCoordinate2D(latitude: 48.8567, longitude: 2.3508)), City(name: "Rome", coordinate: CLLocationCoordinate2D(latitude: 41.9, longitude: 12.5)), City(name: "Washington DC", coordinate: CLLocationCoordinate2D(latitude: 38.895111, longitude: -77.036667)), City(name: iceRink.name, coordinate: CLLocationCoordinate2D(latitude: iceRink.lat, longitude: iceRink.lng)) ] } var body: some View { VStack { Text(iceRink.name) Map(coordinateRegion: $region, annotationItems: annotations) { MapPin(coordinate: $0.coordinate) } .frame(width: 300, height: 300) } } } struct IceRinkView_Previews: PreviewProvider { static var previews: some View { let iceRink = IceRink(name: "Cardiff", lat: 51.48439917004662, lng: -3.177987950883214) IceRinkView(iceRink: iceRink) } }
错误截图

问题原因与修复方案
错误根源在于**@State属性的初始化方式错误以及存储属性初始化顺序不符合Swift要求**:
iceRink是从外部传入的固定数据,不需要用@State修饰(@State仅用于视图内部可修改的状态),应改为普通let属性。- 对于
@State修饰的region,必须通过_region = State(initialValue: ...)的方式在init中初始化,直接赋值会触发初始化顺序错误。
修改后的正确代码
import SwiftUI import CoreLocation import MapKit struct IceRink: Identifiable { let id = UUID() let name: String let lat: Double let lng: Double } struct City: Identifiable { let id = UUID() let name: String let coordinate: CLLocationCoordinate2D } struct IceRinkView: View { private let iceRink: IceRink // 移除@State,改为固定常量 @State private var region: MKCoordinateRegion private let annotations: [City] init(iceRink: IceRink) { self.iceRink = iceRink // 正确初始化@State属性 self._region = State(initialValue: MKCoordinateRegion( center: CLLocationCoordinate2D(latitude: iceRink.lat, longitude: iceRink.lng), span: MKCoordinateSpan(latitudeDelta: 10, longitudeDelta: 10) )) annotations = [ City(name: "London", coordinate: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275)), City(name: "Paris", coordinate: CLLocationCoordinate2D(latitude: 48.8567, longitude: 2.3508)), City(name: "Rome", coordinate: CLLocationCoordinate2D(latitude: 41.9, longitude: 12.5)), City(name: "Washington DC", coordinate: CLLocationCoordinate2D(latitude: 38.895111, longitude: -77.036667)), City(name: iceRink.name, coordinate: CLLocationCoordinate2D(latitude: iceRink.lat, longitude: iceRink.lng)) ] } var body: some View { VStack { Text(iceRink.name) Map(coordinateRegion: $region, annotationItems: annotations) { MapPin(coordinate: $0.coordinate) } .frame(width: 300, height: 300) } } } struct IceRinkView_Previews: PreviewProvider { static var previews: some View { let iceRink = IceRink(name: "Cardiff", lat: 51.48439917004662, lng: -3.177987950883214) IceRinkView(iceRink: iceRink) } }
内容的提问来源于stack exchange,提问作者marmite
相关产品推荐
相关产品推荐

