Как загрузить обновленную переменную в SwiftUI перед запуском просмотра?

avatar
Daniel DE
8 августа 2021 в 19:18
99
1
0

Я нахожусь в процессе создания приложения SwiftUI, но я застрял с начальным значением, которое я передаю переменной для запуска, и что оно не обновляется при загрузке представления.

Я пытался найти некоторые ответы, но ничего не помогло для моего кода.

Я пытаюсь сделать следующее

  1. У меня есть набор данных с местоположениями
  2. Я хочу создать подмножество этих местоположений
  3. Я хочу загрузить первое местоположение из вновь созданного подмножества

Что я спотыкаюсь, так это то, что когда я загружаю карту в первый раз, она по-прежнему поддерживает данные инициализации, а не данные из подмножества

Любая помощь приветствуется, Дэниел

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
    }

}
Источник
vadian
8 августа 2021 в 19:39
0

Вам рекомендуется поместить материал из метода init в модель представления и использовать шаблон observable. В противном случае initialPoint должно быть свойством @State.

Ответы (1)

avatar
Yrb
8 августа 2021 в 19:56
0

У вас есть пара проблем. Во-первых, structs обычно не могут быть изменены, поэтому вы не можете изменять их переменные. Вот почему у нас есть оболочка свойства @State, позволяющая, среди прочего, изменять переменные. Однако простое изменение переменной initialPoint на @State не исправит ситуацию. В том коде, который вы указали, вы, похоже, многое убрали, поскольку ссылаетесь на переменные, которые не инициализированы в вашем MainInterface, но то, что вы показали, не должно компилироваться, поскольку вы пытаетесь передать стандартную переменную initialPoint' to a binding just by adding a $`. Для этого нужна обернутая переменная.

С учетом того, что вы нам дали, я бы инициализировал структуру следующим образом:

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 SwiftUI, чтобы вы начали чувствовать. Эта точная ситуация описана там, но вы разберетесь, как и почему это работает.

Daniel DE
13 августа 2021 в 23:41
0

Это не сработало для меня: / Я буду работать над тем, чтобы сделать полный набор кодов доступным, чтобы воспроизвести проблему.

Yrb
14 августа 2021 в 03:02
0

Нам не нужен полный набор кодов. Нам нужен минимальный воспроизводимый пример.