注意:我是斯威夫特和MapKit的初学者,所以请容忍我。我很感激。我有一个SwiftUI视图,它以ObservableObject作为输入
@ObservedObject var viewModel: PostRowViewModel在这个ObservableObject中有一个@已发布的字段:
@Published var post: Post现在,我要做的是显示一个使用lat和long值的映射,这些值是这个post对象中的字段。现在,MapKit中的Map视图如下:
Map(coordinateRegion: Binding<MKCoordinateRegion>)所以我需要为它提供我想要展示的帖子区域的绑定。我试图做的是按以下方式初始化该区域:
@State var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: viewModel.post.location.coordinate.latitude, longitude: viewModel.post.location.coordinate.latitude), span: MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02))使用来自viewModel的信息。然而,我得到了这个错误:
不能在属性初始化器中使用实例成员“viewModel”;属性初始化器在可用“self”之前运行。
因此,我在网上搜索,发现为了解决这个问题,您需要使用init函数,但是,由于viewModel是作为视图的输入,而且我有环境变量,所以我不想包含init函数。我还尝试在viewModel中创建一个函数,该函数返回绑定,如下所示:
func createMapRegion() -> Binding<MKCoordinateRegion> {
@State var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: post.location.coordinate.latitude, longitude: post.location.coordinate.longitude), span: MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02))
return $region
}但我收到警告:在View上安装时访问State的值。这将导致初始值的持续绑定,而不会更新。因为状态是在外部访问的,所以当我创建映射时,我会这样做:
Map(coordinateRegion: viewModel.createMapRegion())因此,我不确定如何使用viewModel从发布的post对象访问这些信息,并在viewModel作为视图的输入时创建一个地图。
任何帮助都是非常感谢的!
代码:
ViewModel:
import Foundation
import SwiftUI
import MapKit
@MainActor
@dynamicMemberLookup
class PostRowViewModel: ObservableObject, StateManager {
..
@Published var post: Post
..
init(post: Post...) {
self.post = post
...
}
subscript<T>(dynamicMember keyPath: KeyPath<Post, T>) -> T {
post[keyPath: keyPath]
}
}查看:
import SwiftUI
import MapKit
struct PostRowView: View {
.
.
.
@ObservedObject var viewModel: PostRowViewModel
.
.
var body: some View {
// I want to create a map here that uses the post stored in the viewModel.
Map(coordinateRegion: ...)
}
}
}其中,我希望使用Post结构来访问lat和long的值,即:
struct Post: Identifiable, Codable, Equatable {
.
.
.
var location: LocationInfo
.
.
.
}其中LocationInfo是:
struct LocationInfo: Codable, Equatable, Identifiable {
var name: String
var countryCode: String
var coordinate: Coordinate
var id = UUID()
}坐标是:
struct Coordinate: Codable, Hashable {
let latitude, longitude: Double
}发布于 2022-10-03 04:05:30
正如注释中所建议的,最小阻力的路径可能是将region放在ObservableObject上的一个@Published变量中。
class PostRowViewModel: ObservableObject {
@Published var post: Post
@Published var region: MKCoordinateRegion
init(post: Post) {
self.post = post
self.region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: post.location.coordinate.latitude, longitude: post.location.coordinate.longitude), span: MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02))
}
}
struct PostRowView: View {
@ObservedObject var viewModel: PostRowViewModel
var body: some View {
Map(coordinateRegion: $viewModel.region)
}
}请注意,您实际上不需要一个视图模型。你也可以这样做:
struct PostRowView: View {
var post: Post
@State private var region : MKCoordinateRegion = .init()
var body: some View {
Map(coordinateRegion: $region)
.onAppear {
region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: post.location.coordinate.latitude, longitude: post.location.coordinate.longitude), span: MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02))
}
}
}https://stackoverflow.com/questions/73930750
复制相似问题