首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从ObservableObject访问值

从ObservableObject访问值
EN

Stack Overflow用户
提问于 2022-10-03 03:04:29
回答 1查看 77关注 0票数 2

注意:我是斯威夫特和MapKit的初学者,所以请容忍我。我很感激。我有一个SwiftUI视图,它以ObservableObject作为输入

代码语言:javascript
复制
@ObservedObject var viewModel: PostRowViewModel

在这个ObservableObject中有一个@已发布的字段:

代码语言:javascript
复制
@Published var post: Post

现在,我要做的是显示一个使用lat和long值的映射,这些值是这个post对象中的字段。现在,MapKit中的Map视图如下:

代码语言:javascript
复制
            Map(coordinateRegion: Binding<MKCoordinateRegion>)

所以我需要为它提供我想要展示的帖子区域的绑定。我试图做的是按以下方式初始化该区域:

代码语言:javascript
复制
@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中创建一个函数,该函数返回绑定,如下所示:

代码语言:javascript
复制
   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的值。这将导致初始值的持续绑定,而不会更新。因为状态是在外部访问的,所以当我创建映射时,我会这样做:

代码语言:javascript
复制
            Map(coordinateRegion: viewModel.createMapRegion())

因此,我不确定如何使用viewModel从发布的post对象访问这些信息,并在viewModel作为视图的输入时创建一个地图。

任何帮助都是非常感谢的!

代码:

ViewModel:

代码语言:javascript
复制
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]
    }
}

查看:

代码语言:javascript
复制
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的值,即:

代码语言:javascript
复制
struct Post: Identifiable, Codable, Equatable {
    .
    .
    .
    var location: LocationInfo
    .
    .
    .
}

其中LocationInfo是:

代码语言:javascript
复制
struct LocationInfo: Codable, Equatable, Identifiable {
    var name: String
    var countryCode: String
    var coordinate:  Coordinate
    var id = UUID()
}

坐标是:

代码语言:javascript
复制
struct Coordinate: Codable, Hashable {
    let latitude, longitude: Double
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-03 04:05:30

正如注释中所建议的,最小阻力的路径可能是将region放在ObservableObject上的一个@Published变量中。

代码语言:javascript
复制
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)
    }
}

请注意,您实际上不需要一个视图模型。你也可以这样做:

代码语言:javascript
复制
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))
            }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73930750

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档