如何在视图启动之前在 SwiftUI 中加载更新的变量?
Posted
技术标签:
【中文标题】如何在视图启动之前在 SwiftUI 中加载更新的变量?【英文标题】:How to load updated variable in SwiftUI before view initiation? 【发布时间】:2021-08-08 19:18:17 【问题描述】:我正在构建一个 SwiftUI 应用程序,但我被初始值卡住了,我为启动提供了一个变量,并且在我加载视图时它不会更新。
我已尝试寻找一些答案,但对我的代码没有任何帮助。
我想要做的是以下
-
我有一个包含位置的数据集
我想创建这些位置的子集
我想从新创建的子集中加载第一个位置
我遇到的问题是,一旦我第一次加载地图,它仍然会保留初始数据,而不是子集中的数据
任何帮助表示赞赏, 丹尼尔
import SwiftUI
import CoreData
import MapKit
struct MainInterface: View
@Environment(\.presentationMode) var presentationMode
var initialPoint: Places = totalData[1]
init()
let subset1 = Array(Set(totalData.filter(
$0.Area == 1
)))
.prefix(3)
let subset2 = Array(Set(totalData.filter(
$0.Area == 2
)))
.prefix(3)
levelSet = Array(subset1) + Array(subset2)
self.initialPoint = levelSet[0]
var body: some View
VStack(spacing: 0)
SubView(initialPoint: $initialPoint)
.onAppear
//levelSet = Array(level1set) + Array(level2set)
//self.initialPoint = levelSet[0]
import SwiftUI
import MapKit
struct SubView: UIViewRepresentable
@Binding var initialPoint: Place
let mapView = MKMapView()
func makeUIView(context: Context) -> MKMapView
mapView.delegate = context.coordinator
return mapView
func updateUIView(_ view: MKMapView, context: Context)
func makeCoordinator() -> Coordinator
Coordinator(self)
class Coordinator: NSObject, MKMapViewDelegate, UIGestureRecognizerDelegate
var parent: SubView
init(_ parent: SubView)
self.parent = parent
super.init()
self.parent.mapView.setRegion(MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: self.parent.initialPoint.Latitude, longitude: self.parent.initialPoint.Longitude), span: MKCoordinateSpan(latitudeDelta: 10, longitudeDelta: 10)), animated: true)
func mapViewDidChangeVisibleRegion(_ mapView: MKMapView)
parent.region = mapView.region
parent.centerCoordinate = mapView.centerCoordinate
【问题讨论】:
鼓励您将init
方法中的内容放入视图模型并使用observable 模式。否则 initialPoint
应该是 @State
属性
【参考方案1】:
这里有几个问题。首先,structs
不能正常修改,所以不能修改它们的变量。这就是为什么我们有@State
属性包装器等,以允许更改变量。但是,简单地将initialPoint
变量更改为@State
并不能解决所有问题。在您给出的代码中,您似乎已经删除了很多东西,因为您引用了未在 MainInterface
中初始化的变量,但是您所显示的内容不应该编译,因为您试图传递一个标准变量 @ 987654328@$`。这需要一个包装变量才能使用。
有了你给我们的,我会这样初始化结构:
struct MainInterface: View
@Environment(\.presentationMode) var presentationMode
// make this @State if you need to pass it to a binding.
@State var initialPoint: Places
init(totalData: TotalData) //I have know idea what the `Type` of totalData is
//as you never defined it in the struct. Substitute its actual `Type` here.
let subset1 = Array(Set(totalData.filter(
$0.Area == 1
)))
.prefix(3)
let subset2 = Array(Set(totalData.filter(
$0.Area == 2
)))
.prefix(3)
levelSet = Array(subset1) + Array(subset2)
// This will initialize `initialPoint` as a State variable
_initialPoint = State(initialValue: levelSet[0])
// It seems to me that you have gone to a great deal of trouble to initialize
// `initialPoint` to be the first element in the `subset1` array slice. I am not
// sure what the point of creating your array slice as it is never used outside
// of the `init()`
我将从Apple's SwiftUI tutorials 开始,以便您开始感受。那里涵盖了这种确切的情况,但您将了解它的工作方式和原因。
【讨论】:
这对我不起作用:/我将努力提供完整的代码集以复制问题。 我们不想要完整的代码集。我们想要一个Minimal, Reproducible Example。以上是关于如何在视图启动之前在 SwiftUI 中加载更新的变量?的主要内容,如果未能解决你的问题,请参考以下文章
在列表中加载 WebView 而无需重新加载 webView 内容 SwiftUI
如何在 UITabBarController 中加载所有视图?