Und gleich eine neue Frage, da ich ja lernen will....Verrechnung von Daten aus verschiedenen ViewControllern....

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

  • Und gleich eine neue Frage, da ich ja lernen will....Verrechnung von Daten aus verschiedenen ViewControllern....

    Da das mit dem NumberFormatter dank my Mattes ja so Klasse geklappt hat, habe ich gleich mal eine neue Frage da ich ja lernen will.

    Ich habe eine neue App zu Testzwecken erstellt.
    Diese hat drei ViewController.

    Im MainViewController gibt es zwei Buttons.
    Klickt man auf den ersten Butten, kommt man zur Eingabe der Länge eines Rechecks.
    Klickt man auf den zweiten Butten, kommt man zu Eingabe der Breite.

    Zur Zeit bin ichi soweit, dass im MainViewController diese beide Daten in Labels ausgegeben werden.
    Sogar die letzte Eingabe wird gespeichert...cool! :)

    Nun würde ich aber gerne im MainViewport verschiedene Berechnungen mit diesen beiden Daten vornehmen,
    Z.B Umfang und Fläche und diese wiederum in neuen Labels ausgeben.

    Ich schaffe es aber nicht die Daten aus den Textfeldern von VC1 + VC2 zu verrechnen um die im MainVC in verschiedenen Labels auszugeben.
    Mache ich da alles in einem Viewport, ist das kein Problem.

    WIe ist das möglich?
    Irgendwie geht das sicher, mir ist nur noch nicht bewusst wie ich das anstellen soll.....
  • Moin.
    Am Besten hälst du dir dafür eine Model-Klasse welche deine Daten aufnehmen kann.

    Dann erstellst du dir im ersten ViewController (Denke mal dein MainViewController) eine Instanz deiner Model-Klasse und reichst diese entsprechend weiter. Entsprechend kannst du sie dann in jedem weiteren ViewController verarbeiten oder was auch immer.
  • Danke für die Antwort, werde mir das ganze mal ansehen....

    Ist es denn eigentlich auch möglich Daten aus einem Label zu übernehmen um diese zu verrechnen ?

    Bedeutet genau, ich klicke auf einen Button, ein neuer VC öffnet sich und ich trage meine Daten im neuen VC in ein Textfeld ein,
    Dieser sendet diese an den Ausgangs VC in ein Label.

    Kann man aus diesem Label die Daten entnehmen und in eine Formel einbinden ?
  • Hmm, also ich schnalle es einfach nicht, egal was ich probiere....
    Es gelingt mir einfach nicht Zahlen aus einem Label in eine Formel zu packen.

    wo in diesem Code muss ich ansetzen, um die Zahlen zu verrechnen ?
    Inzwischen gibt es vier Buttons, die jeweils auf einen eigenen Viewcontroller verweisen in denn man eine Zahl eingeben kann.
    Im ersten Viewcontroller werden diese auch jeweils in einem Label angezeigt. Ja sogar die letzte eingegebene Zahl wird gespeichert und wieder ausgegeben.

    Ich schaffe es allerdings nicht, diese vier Zahlen zu addieren und in einem neuen Label im ersten ViewController auszugeben.

    hier mal ein Foto meines mainStoryboards...


    und hier der Code des ersten Viewports...


    Quellcode

    1. import UIKit
    2. class ViewController: UIViewController, sendValue1, sendValue2, sendValue3, sendValue4 {
    3. @IBOutlet weak var value1: UILabel!
    4. @IBOutlet weak var value2: UILabel!
    5. @IBOutlet weak var value3: UILabel!
    6. @IBOutlet weak var value4: UILabel!
    7. @IBOutlet weak var calculatedValue1: UILabel! // hier sollen die Zahlen der Labels verrechnet werden. Z.B. value1 + vlaue2 + value3 + value 4
    8. @IBOutlet weak var calculatedValue2: UILabel! // hier soll das ganze nocjmals verrechnet werden allerdings mit -- oder + oder ws auch immer....
    9. func value1Data(data: String) {
    10. value1.text = data
    11. UserDefaults.standard.set(value1.text, forKey: "value1")
    12. }
    13. func value2Data(data: String) {
    14. value2.text = data
    15. UserDefaults.standard.set(value2.text, forKey: "value2")
    16. }
    17. func value3Data(data: String) {
    18. value3.text = data
    19. UserDefaults.standard.set(value3.text, forKey: "value3")
    20. }
    21. func value4Data(data: String) {
    22. value4.text = data
    23. UserDefaults.standard.set(value4.text, forKey: "value4")
    24. }
    25. override func viewDidAppear(_ animated: Bool) {
    26. if let lastValue1Data = UserDefaults.standard.object(forKey: "value1") as? String {
    27. value1.text = lastValue1Data
    28. }
    29. if let lastValue2Data = UserDefaults.standard.object(forKey: "value2") as? String {
    30. value2.text = lastValue2Data
    31. }
    32. if let lastValue3Data = UserDefaults.standard.object(forKey: "value3") as? String {
    33. value3.text = lastValue3Data
    34. }
    35. if let LastValue4Data = UserDefaults.standard.object(forKey: "value4") as? String {
    36. value4.text = LastValue4Data
    37. }
    38. }
    39. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    40. if segue.identifier == "VC1" {
    41. let SendingVC1: Value1ViewController = segue.destination as! Value1ViewController
    42. SendingVC1.delegate = self
    43. }
    44. if segue.identifier == "VC2" {
    45. let SendingVC2: Value2ViewController = segue.destination as! Value2ViewController
    46. SendingVC2.delegate = self
    47. }
    48. if segue.identifier == "VC3" {
    49. let SendingVC3: Value3ViewController = segue.destination as! Value3ViewController
    50. SendingVC3.delegate = self
    51. }
    52. if segue.identifier == "VC4" {
    53. let SendingVC4: Value4ViewController = segue.destination as! Value4ViewController
    54. SendingVC4.delegate = self
    55. }
    56. }
    57. @IBAction func unwindToView1(_ segue: UIStoryboardSegue) {
    58. }
    Alles anzeigen
    Könnt ihr mir bitte einen Rat geben wie das funktioniert?
    Ich würde das so gerne verstehen!
    Bilder
    • Viewports.jpg

      30,17 kB, 637×630, 79 mal angesehen

  • Wenn Du in Deinem Textfeld genauso wie hier bei Deinem Post statt der Ziffer 0, einen Buchstaben ob groß O oder klein o, eingibst kommt natürlich keine Zahl dabei raus… ;)

    Warum verwendest Du Float und nicht Double? Gibt es dafür einen Grund? Double ist üblicherweise der Standard-Fließkomma-Typ in Swift.

    Und um Dir Deine Frage (vermutlich) wirklich zu beantworten: Die Initializer von Float und Double (und auch Int, etc.) sind nicht lokalisiert. D.h. Double("0.5") ergibt 0.5 und Double("0,5") ergibt nil.
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • Alles, wirklich alles an Daten verwaltest Du in Deinem DatenModel. Dazu erzeugst Du eine eigene Klasse (einen „DatenController“), wo Du die Daten hältst (in Instanzvariablen). Dort machst du auch die Berechnungen, wenn sich an den Daten etwas ändert. Überwacht werden solche Änderungen über Key-Value-Coding (Google mal).
    Soviel zum „falschen“ Titel dieses Threads.

    Wenn Deine Viewcontroller initialisiert werden, speicherst Du in jedem einen Zeiger zum DatenController. Ändert sich an dem Wert etwas, bekommt das der Viewcontroller mit und gibt dies an den DatenController weiter. Das kann über einen „Pfad“ auch praktisch automatisch gehen. Schau mal nach „Binding“ und eben Key-Value-Coding.

    Vergiß, dass ein Viewcontroller oder gar ein UI-Element irgendwelche Daten hält. Es zeigt sie nur (im richtigen) Format an oder nimmt Getipptes entgegen und reicht sie sofort an das Datenmodell weiter - wo eben die Daten sind.

    Wenn Du verfügbare Techniken verwendest, musst Du dich um diese Kommunikation selbst nicht kümmern, geht alles automatisch.
  • Also irgendwie komme ich nicht wirklich weiter mit meiner kleinen Rechenapp.

    Ich habe alle nochmals umgebaut.

    Die Struktur ist nun so, dass ich einen MainviewController habe in dem alle Daten angezeigt werden.


    Quellcode

    1. import UIKit
    2. class MainViewController: UIViewController, sendWidthData, sendLengthData {
    3. @IBOutlet weak var widthLbl: UILabel!
    4. @IBOutlet weak var lenghtLbl: UILabel!
    5. @IBOutlet weak var calculationLbl: UILabel!
    6. // Show Data in Labels
    7. func widthData(data: String) {
    8. widthLbl.text = data
    9. UserDefaults.standard.set(widthLbl.text, forKey: "width")
    10. }
    11. func lengthData(data: String) {
    12. lenghtLbl.text = data
    13. UserDefaults.standard.set(lenghtLbl.text, forKey: "lenght")
    14. }
    15. // Data From ohter ViewControllers
    16. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    17. if segue.identifier == "toWidth" {
    18. let sendVC: WidthViewController = segue.destination as! WidthViewController
    19. sendVC.delegate = self
    20. }
    21. if segue.identifier == "toLength" {
    22. let sendVC: LengthViewController = segue.destination as! LengthViewController
    23. sendVC.delegate = self
    24. }
    25. }
    26. // Last stored Data
    27. override func viewDidAppear(_ animated: Bool) {
    28. if let lastWidthData = UserDefaults.standard.object(forKey: "width") as? String {
    29. widthLbl.text = lastWidthData
    30. }
    31. if let lastLenghtData = UserDefaults.standard.object(forKey: "lenght") as? String {
    32. lenghtLbl.text = lastLenghtData
    33. }
    34. }
    35. }
    Alles anzeigen




    Für die Eingabe der Daten gibt es zwei weitere ViewController, die nur dafür zuständig sind, die eingegebenen Daten im Label desselben anzuzeigen. Z.B. für den LenghViewController:

    Quellcode

    1. import Foundation
    2. class Length {
    3. private var _lenght = "length"
    4. var lenght: String {
    5. get {
    6. return _lenght
    7. }
    8. set {_lenght = newValue
    9. }
    10. }
    11. }
    Alles anzeigen
    der LenthViewController selbst zeigt den eingegebenen Wert auch brav an und schickt per delegate die Daten weiter ins ein Label der MainViewControllers...

    der LengthViewController:

    Quellcode

    1. import UIKit
    2. protocol sendLengthData {
    3. func lengthData(data: String)
    4. }
    5. class LengthViewController: UIViewController {
    6. var delegate: sendLengthData? = nil
    7. @IBOutlet weak var lengthLbl: UILabel!
    8. @IBOutlet weak var enterLengthTxt: UITextField!
    9. // delegate to MainviewController Label
    10. @IBAction func done(_ sender: Any) {
    11. if delegate != nil {
    12. if enterLengthTxt.text != nil {
    13. let dataFromLength = enterLengthTxt.text
    14. delegate?.lengthData(data: dataFromLength!)
    15. }
    16. }
    17. // Show in LengthViewController Label
    18. let calc = Length()
    19. calc.lenght = enterLengthTxt.text!
    20. lengthLbl.text = "\(calc.lenght)"
    21. UserDefaults.standard.set(lengthLbl.text, forKey: "length")
    22. }
    23. // last Data if view did appear
    24. override func viewDidAppear(_ animated: Bool) {
    25. if let lastLengthData = UserDefaults.standard.object(forKey: "length") as? String {
    26. lengthLbl.text = lastLengthData
    27. }
    28. }
    29. }
    Alles anzeigen

    So weit do gut, ich habe also schon mal wie mir weiter oben im Thread empfohlen wurde, die Daten vom Viewcontoller getrennt und verarbeite diese in einer ModelDatei. (Lenght.swift)

    Nun habe ich mir noch eine Swift Datei erstellt, in der alle Berechnungen erfolgen sollen, die dann automatisch im MainViewController ausgegeben werden sollen in Labels. Diese sieht zur Zeit so aus:


    Quellcode

    1. import UIKit
    2. class Calculations {
    3. var length: Double?
    4. var width: Double?
    5. }
    6. class CalcSqm: Calculations {
    7. func getSqm() -> String {
    8. let sqm = width! * length!
    9. return "\(sqm)"
    10. }
    11. }
    12. class CalcPlus: Calculations {
    13. func getPlus() -> String {
    14. let plus = width! + length!
    15. return "\(plus)"
    16. }
    17. }
    Alles anzeigen
    Ich habe also eine Klasse mit zwei "Unterklassen" erstellt, in welchen die Berechnungen gemacht werden und sich die Daten aus der Klasse "Calculations" holen.
    Funktioniertja auch prima, zumindest meckert Xcode nicht.... :D

    Was mir jetzt aber fehlt und worauf ich nicht komme ist, wie lasse ich per klick auf einen der Buttons im LenghtViewController oder des WidthViewcontrollers den Variablen " lenght" und "width" in der Klasse "Calculations" wissen, welcher Wert eingegeben wurde damit diese auch verarbeitet werden können?

    Ich hoffe, dass ist alles halbwegs verständlich geschrieben...bin mir da nicht ganz so sicher gerade... :)

    Ich hoffe ihr könnt mich da ein wenig unterstützen.

    Vielen Dank
    Thomas
  • Ich glaube, Du solltest Dich einmal (kurzzeitig) vom Code verabschieden und Dir aufmalen, welche Objekte Du in Deiner App verwendest bzw. verwenden willst und welche Beziehungen zwischen diesen bestehen müssen: Eine Klasse für das Datenmodell zu verwenden, ist sicherlich richtig, aber was sollen Deine zwei "Unterklassen"? Was nützt Dir die Definition einer Klasse, wenn Du diese nie instanzierst?

    Mit Swift kann ich Dir nicht helfen, aber konzeptionell würde ich Deine App wie folgt modellieren:
    1. Ein App-Delegate, dieser erzeugt drei Objekte: Ein Daten-Modell und zwei View-Controller
    2. Der Modell-Controller dient der Datenhaltung und Verarbeitung. Er hat für jeden Wert ein Property und für jede Berechnung eine Methode ... öffentlich natürlich.
    3. Die beiden View-Controller sind für die Eingabe zuständig (die könnten eigentlich von der gleichen Klasse abstammen): Diese rufen z. B. eine Methode der App-Delegates auf, die den Eingabewert dann im Model speichert. Oder das Modell wird ihnen als Delegate übergeben und sie rufen dort eine entsprechende Methode auf. Diesen Weg finde ich aber suboptimal, da er die Schnittstellen zum Modell in die View-Controller verlagert: Unnötige Abhängigkeiten und m. E. nicht im Sinne von MVC.
    Gruss, Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.