Probleme mit Argumente an Klasse zu übergeben

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Probleme mit Argumente an Klasse zu übergeben

    Hallo,

    ich probiere in SwiftUI eine Map in einer View darzustellen. Ich habe mir dazu Konstrukt aus einem Apple Developer Form Thread genutzt, welches auch einwandfrei funktioniert:

    Quellcode

    1. class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
    2. @Published var region = MKCoordinateRegion()
    3. private let manager = CLLocationManager()
    4. override init() {
    5. super.init()
    6. manager.delegate = self
    7. manager.desiredAccuracy = kCLLocationAccuracyBest
    8. manager.requestWhenInUseAuthorization()
    9. manager.startUpdatingLocation()
    10. }
    11. func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation], latitudeDelta: Double) {
    12. locations.last.map {
    13. let center = CLLocationCoordinate2D(latitude: $0.coordinate.latitude, longitude: $0.coordinate.longitude)
    14. let span = MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005)
    15. region = MKCoordinateRegion(center: center, span: span)
    16. }
    17. }
    18. }
    Alles anzeigen

    Aufgerufen wird das dann in meiner View:

    Quellcode

    1. var body: some View {
    2. ZStack {
    3. Color.Neumorphic.main.edgesIgnoringSafeArea(.all)
    4. VStack {
    5. Map(coordinateRegion: $manager.region, showsUserLocation: true)
    6. ...
    7. ...

    In der Klasse in der die Map initialisiert wird gibt es Span Werte um den Zoom Faktor zu bestimmen:

    Quellcode

    1. let span = MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005)
    Die beiden Double Werte würde ich jetzt gerne in einer Settings View über den User setzen lassen (Picker).
    Meine Idee war es die Werte über @State und @Binding der View zu übergeben.

    Wo mir jetzt allerdings das KnowHow fehlt, ja ich weiß hier muss ich in Swift noch Gas geben, ist das Vorgehen wie ich der Klasse LocationManager und der darin erhaltenden Funktion die Werte übergeben kann ??

    Gruß

    Ralf
  • Hallo Wolf,

    ich nutze ja Map aus Mapkit. Die Darstellung der Map funktioniert soweit ja auch gut ich würde nur gerne verstehen/lernen wie ich die Double Werte in Span von außen setzen kann, sprich der User kann in einer Settings View den initialen Zoom Faktor vorbelegen.

    Über @State und @Binding kann ich den Wert aus der Settings View der Map View übergeben. Jetzt weiß ich nur nicht wie das in die Klasse LocationManager bekomme.

    Hast Du da vielleicht eine Idee?

    Gruss Ralf
  • Hallo zusammen,

    ich habe es bei mir jetzt folgendermaßen "gelöst", bin mir aber nicht sicher ob das eine gute Lösung ist, bzw. ob die Lösung Nachteile hat die ich aktuell nicht abschätzen kann.
    Ich habe ein der MapView eine Variable "spanValue" deklariert, welche ich in der LocationManager Klasse als Wert für span nutze.
    Wenn ich MapView aufrufe, setze ich in .onAppear den Wert der Variablen spanValue auf den Wert der @Binding Variable die über den Picker in der Einstellungen View gesetzt wurde.

    Quellcode

    1. public var spanValue: Double = 1.0
    2. class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
    3. ...
    4. ...
    5. func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    6. locations.last.map {
    7. let center = CLLocationCoordinate2D(latitude: $0.coordinate.latitude, longitude: $0.coordinate.longitude)
    8. let span = MKCoordinateSpan(latitudeDelta: spanValue, longitudeDelta: spanValue)
    9. region = MKCoordinateRegion(center: center, span: span)
    10. }
    11. }
    12. struct MapView: View {
    13. ...
    14. ...
    15. .onAppear() {
    16. // Set span value used by LocationManager class
    17. spanValue = 0.25 / (Double(zoomFactorIndex*zoomFactorIndex)+1.0)
    18. }
    Alles anzeigen
    Gruß

    Ralf
  • Du weisst schon, was passiert wen dein Ausdruck 0 ergibt?

    Quellcode

    1. (Double(zoomFactorIndex*zoomFactorIndex)+1.0)
    So, das meinst damit, wie man einen Wert übergeben kann. Tja, da gibts mehrere Möglichkeiten

    1. State
    2. let
    3. Binding
    4. init(…
    5. OnAppear
    6. Observed Object
    7. Environment
    8. EnvironmentObject
    9. Nachrichten
    10. Appdata,
    11. CoreData
    12. JSon
    13. File System
    14. Combine
    15. … und wohl noch vieles mehr
  • Hallo Wolf,

    Wolf schrieb:

    Du weisst schon, was passiert wen dein Ausdruck 0 ergibt?
    Ja (Division by zero -> crash) , daher auch die +1 ;) Ich habe einen Picker und die Werte sind 0-9(Array . Also sollte dieser Ausdruck nicht 0 werden können, oder habe ich was übersehen. Ich weiß, es ist nicht ganz so clever,
    habe im ersten Schritt nur nach einer Möglichkeit gesucht die span Werte über einen einfachen Mechanismus kleiner werden zu lassen -> je kleiner span desto größer der Zoom Faktor in der Map. Initial gehe ich mit z.B. span = 0.25 rein, und wenn ich den
    Picker dann auf z.B. 2 Stelle ergibt sich ein span von 0,05 usw.

    Danke für die Aufzählung .. da ich Binding und onAppear benutzt habe, und diese in Deiner Aufzählung vorkommen, liege ich ja nicht ganz falsch :rolleyes:

    Gruß

    Ralf

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von ralfb ()

  • Kannst es ja auch einfach davor prüfen, ob da 0 rauskommt und anderenfalls einen Standardwert setzen :) (alternativ kannst auch mit Exceptions schaffen...)


    @Binding heisst nur, dass der Wert Bidirektional geändert werden kann. Wenn Du das nicht brauchst, ist let, init... nicht verkehrt. Aber auch da könntest ja Referenzen statt Werte übergeben (bspw. via Objekte).

    Der grosse Unterschied zwischen onAppear und init ist, dass bei OnAppear die Variablen bereits initialisiert sein müssen, daneben kannst du mit init auch noch andere Vars übergeben, welche Du nur für das Initialisieren benötigst und später nicht mehr.
  • Hallo Wolf,

    das mit dem Check auf 0 werde ich einbauen, Vorsicht ist besser als Nachsicht ;)
    Das mit @State und @Binding habe ich genommen um Werte zwischen den Views auszutauschen.
    Generell, JA - mir fehlen noch viele Grundlagen und ich versuche die über Udemy Kurse zu erlangen.

    Zu dem init, wo würde ich den denn einbauen und was genau macht man mit dem init alles? Der onAppear ist mir klar, daher habe ich ihn auch genutzt :saint:


    Gruß
    Ralf