web-dev-qa-db-fra.com

Passage rapide des données calculées au contrôleur de vue précédent

Je crée ma première application de budgétisation simple. Fondamentalement, je prends quelques données utilisateur comme un objectif de revenu et d’épargne mensuel. Ensuite, ils cliquent sur "démarrer", et l'application calcule des éléments tels que leur budget quotidien, etc. 

Ici, j'ai des ennuis. Après tous les calculs, j'affiche "combien vous pouvez dépenser chaque jour" (par exemple, 20 dollars par jour), que je répercute d'avance sur leurs séquences d'origine à partir de leurs entrées d'origine sur l'écran d'origine. 

Maintenant, dans ce VC (UserInfoVC), j'ai créé un bouton qui leur permet d'ajouter combien d'argent ils ont dépensé aujourd'hui. Alors, quand ils cliquent sur ce bouton "Ajouter de l’argent dépensé", j’ouvre un nouveau VC (AddSubtractMoney) dans lequel je présente une calculatrice dans laquelle ils peuvent entrer le montant dépensé aujourd’hui (12 $) et cliquer sur Soumettre. 

Je gère leur contribution par rapport à leur budget quotidien pour obtenir un nouveau budget quotidien. 

Maintenant, je ne parviens pas à renvoyer ce numéro mis à jour à l'envers, pour l'afficher sur le VC précédent sur l'étiquette "dailySpendingLimitLabel". Je sais que les ligues ne sont pas la meilleure façon de transférer les données en arrière. 

J'ai essayé des fermetures, mais je finis par me perdre dans la syntaxe, les protocoles et les délégués (c'est le codage de mon deuxième mois). 

Existe-t-il un moyen simple de transférer ces données à l'ancien VC et de les renseigner dans cette étiquette d'affichage précédente?

Ci-dessous le code. 

Le premier extrait provient de UserInfoVC, où j’affiche les données initialement saisies que j’ai classées. Le deuxième extrait provient de la classe AddSubtractMoney où j'ai placé la calculatrice et créé un objet "latestUpdate" dans une fonction qui me permet de calculer le nombre entré sur la calculatrice moins leur ancien budget quotidien. Pour arriver à un nouveau budget que je veux présenter à l’arrière de la UserInfoVC.

class UserInfoViewController : ViewController {

var userNamePassedOver : String?
var userDailyBudgetPassedOver : Double = 99.0
var userDailySavingsPassedOver : Double = 778.00
var userMonthlyEarningsPassedOver : Double?
var userDesiredSavingsPassedOver : Double?
var newAmountPassedBack : Double = 0.0


@IBOutlet weak var dailySavingsNumberLabel: UILabel!
@IBOutlet weak var userNameLabel: UILabel!
@IBOutlet weak var dailySpendingLimitLabel: UILabel!



override func viewDidLoad() {
    super.viewDidLoad()

    userNameLabel.text = userNamePassedOver
    dailySpendingLimitLabel.text = String(format: "%.2f", userDailyBudgetPassedOver)
    dailySavingsNumberLabel.text = String(format: "%.2f", userDailySavingsPassedOver)

}


@IBAction func addSubtractMoneyPressed(_ sender: UIButton) {

    performSegue(withIdentifier: "addOrSubtractMoney", sender: self)


}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "addOrSubtractMoney"{

        let addOrSubtractMoneyVC = segue.destination as! AddSubtractMoney

            addOrSubtractMoneyVC.dailyBudgetPassedThrough = userDailyBudgetPassedOver
        }
    }

}

extension UserInfoViewController: AddSubtractMoneyDelegate {

func calculatedValue(value: Double) {

    dailySpendingLimitLabel.text = String(userDailyBudgetPassedOver - value)

}

}

import UIKit

protocol AddSubtractMoneyDelegate {
  func calculatedValue(value: Double)
}

class AddSubtractMoney: UIViewController {

@IBOutlet weak var outputLabel: UILabel!

var runningNumber = ""
var finalNumberPassedOver : Double?
var amountPassedBackToUserInfo : Double = 0.0
var dailyBudgetPassedThrough : Double = 0.0

var delegate: AddSubtractMoneyDelegate?

override func viewDidLoad() {
    super.viewDidLoad()

    outputLabel.text = "0"


    // Do any additional setup after loading the view.
}


@IBAction func buttonPressed(_ sender: UIButton) {
    runningNumber += "\(sender.tag)"
    outputLabel.text = runningNumber


}

@IBAction func submitNewInfo(_ sender: UIButton) {

    // FIX FIX

    AddSubtractMoneyController.addToMoneySpentArray(amountISpent: outputLabel.text!)

    sendBackUpdatedNumber()

    dismiss(animated: true, completion: nil)

}


@IBAction func allClearedPressed(_ sender: UIButton) {
    runningNumber = ""
    outputLabel.text = "0"
}

// THIS LINE PRODUCES THE CORRECT INPUT IN OUTPUT CONSOLE WHEN I PRINT- BUT I CANT FIGURE HOW TO TRANSFER IT BACK TO PREVIOUS VC

func sendBackUpdatedNumber(){

    let newestUpdate = UserInfo(whatYouSpentToday: runningNumber, oldDailyBudgetPassed: dailyBudgetPassedThrough)

   amountPassedBackToUserInfo = dailyBudgetPassedThrough - Double(runningNumber)!
   newestUpdate.goalToSaveDaily = amountPassedBackToUserInfo

    print(amountPassedBackToUserInfo)

    self.delegate?.calculatedValue(value: amountPassedBackToUserInfo)


}


}
4

Ma suggestion est d'utiliser une fermeture de rappel. C'est moins de code et plus facile à gérer que protocole/délégué.

Dans AddSubtractMoney déclarez une variable callback et appelez-la dans sendBackUpdatedNumber en passant la valeur Double

class AddSubtractMoney: UIViewController {

   // ...

    var callback : ((Double)->())?

  // ...

    func sendBackUpdatedNumber(){

        let newestUpdate = UserInfo(whatYouSpentToday: runningNumber, oldDailyBudgetPassed: dailyBudgetPassedThrough)
        amountPassedBackToUserInfo = dailyBudgetPassedThrough - Double(runningNumber)!
        newestUpdate.goalToSaveDaily = amountPassedBackToUserInfo
        print(amountPassedBackToUserInfo)
        callback?(amountPassedBackToUserInfo)
    }
}

Dans prepare(for segue, affectez la fermeture à la variable callback et ajoutez le code à exécuter au retour.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "addOrSubtractMoney"{
        let addOrSubtractMoneyVC = segue.destination as! AddSubtractMoney
        addOrSubtractMoneyVC.callback = { result in
             print(result)
            // do something with the result
        }
        addOrSubtractMoneyVC.dailyBudgetPassedThrough = userDailyBudgetPassedOver
    }
}
6
vadian

Utiliser délégué 

if segue.identifier == "addOrSubtractMoney" {

    let addOrSubtractMoneyVC = segue.destination as! AddSubtractMoney

        addOrSubtractMoneyVC.dailyBudgetPassedThrough = userDailyBudgetPassedOver

       addOrSubtractMoneyVC.delegate = self
    }
}

Vous devez ajouter la propriété delegate à la classe AddSubtractMoney

var delegate: AddSubtractMoneyDelegate?

Créer un protocole dans la classe AddSubtractMoney 

protocol AddSubtractMoneyDelegate {
  fun calculatedValue(value: Double)
}

Et répondre au délégué

 func sendBackUpdatedNumber(){

    let newestUpdate = UserInfo(whatYouSpentToday: runningNumber, oldDailyBudgetPassed: dailyBudgetPassedThrough)

   amountPassedBackToUserInfo = dailyBudgetPassedThrough - Double(runningNumber)!
   newestUpdate.goalToSaveDaily = amountPassedBackToUserInfo

    print(amountPassedBackToUserInfo)

    self.delegate.calculatedValue(value: amountPassedBackToUserInfo)
}

Maintenant, vous devez implémenter cette méthode déléguée dans la classe où délégué est défini.

Ici, dans UserInfoViewController, le délégué de classe est défini, vous devez donc implémenter sa méthode de délégué.

extension UserInfoViewController: AddSubtractMoneyDelegate {

  func calculatedValue(value: Double) {

       //set label here
  } 

}
2
Mahendra GP

Si vous ne sous-entendez pas le processus derrière un délégué (orienté protocole), vous pouvez simplement consulter le code ci-dessous. cela ne fonctionne que si les deux classes 

Mais ce n'est pas une bonne pratique En savoir plus sur la diffusion par protocole, fermeture ou Notification Center pour les méthodes de codage les plus utilisées, flexibles et réutilisables.

UserInfoViewController

class UserInfoViewController : ViewController {
   fun receiveBackUpdatedNumber(numberString:String){

   }

   override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      if segue.identifier == "addOrSubtractMoney"{
        let addOrSubtractMoneyVC = segue.destination as! AddSubtractMoney
      addOrSubtractMoneyVC.userInfoViewController = self
        }
      }

   }
 }

AddSubtractMoney

class AddSubtractMoney: UIViewController {
  var userInfoViewController: UserInfoViewController!
  var updatedNumber = ""
  func sendBackUpdatedNumber(){
    self.userInfoViewController.receiveBackUpdatedNumber(numberString: updatedNumber)
   }
}

Si vous êtes sûr, vous pouvez utiliser des protocoles. Les protocoles insistent pour qu'une classe implémente une méthode, qui rend le code plus réutilisable et indépendant.

Dans la méthode ci-dessus, nous transmettons l'instance du contrôleur de vue actuel (UserInfoViewController) au contrôleur de vue suivant (AddSubtractMoney) lors de l'exécution de la séquence. Ainsi, nous pouvons accéder aux propriétés de la fonction dansUserInfoViewControllerfromAddSubtractMoney. Il est donc facile de passer des données de AddSubtractMoney à -> UserInfoViewController

0
Britto Thomas

Vous pouvez aussi éventuellement utiliser un undind segue pour renvoyer les données.

0
Balázs Vincze