我正在创建我的第一个简单预算应用。基本上,我采取了一些用户输入,如月收入和储蓄目标。然后他们点击“开始”,&该应用程序计算的东西,如他们的每日预算等。
我遇到了麻烦。在完成所有计算之后,我会显示“您每天可以花多少钱”(例如每天20美元),我会通过原始屏幕上的原始输入传递segue。
现在,在这个VC(UserInfoVC
)中,我创建了一个按钮,可以让他们添加今天花了多少钱。因此,当他们点击这个“花钱”按钮时,我打开一个新的VC(AddSubtractMoney
),在那里我提供一个计算器,他们可以输入他们今天花了多少钱(即12美元)并点击提交。
我将他们的输入与每日预算相比较,以获得新的每日预算。
现在,我无法向后传递此更新的数字,将其显示在标签“dailySpendingLimitLabel”上的前一个VC上。我知道segues不是向后传递数据的最佳方式。
我已经尝试过闭包,但我最终迷失在语法,协议和代理中(这是我的第二个月编码)。
是否有一种简单的方法可以将此数据传回上一个VC并填充上一个显示标签中的数据?
以下是代码。
第一个片段来自UserInfoVC,我在其中显示我最初输入的数据。第二个片段来自我放置计算器的AddSubtractMoney
类,并在一个函数内创建了一个对象“newestUpdate”,这个对象允许我计算他们在计算器上输入的数字减去旧的每日预算。要获得新预算,我希望向后呈现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)
}
}
答案 0 :(得分:10)
我的建议是使用回调闭包。它比协议/代理更少的代码和更容易处理。
在AddSubtractMoney
中声明callback
变量,并在sendBackUpdatedNumber
中调用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)
}
}
在prepare(for segue
中将闭包分配给callback
变量并添加要在返回时执行的代码
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
}
}
答案 1 :(得分:2)
使用委托
if segue.identifier == "addOrSubtractMoney" {
let addOrSubtractMoneyVC = segue.destination as! AddSubtractMoney
addOrSubtractMoneyVC.dailyBudgetPassedThrough = userDailyBudgetPassedOver
addOrSubtractMoneyVC.delegate = self
}
}
您需要在delegate
类
AddSubtractMoney
属性
var delegate: AddSubtractMoneyDelegate?
在AddSubtractMoney
类
protocol AddSubtractMoneyDelegate {
fun calculatedValue(value: Double)
}
回复代表
func sendBackUpdatedNumber(){
let newestUpdate = UserInfo(whatYouSpentToday: runningNumber, oldDailyBudgetPassed: dailyBudgetPassedThrough)
amountPassedBackToUserInfo = dailyBudgetPassedThrough - Double(runningNumber)!
newestUpdate.goalToSaveDaily = amountPassedBackToUserInfo
print(amountPassedBackToUserInfo)
self.delegate.calculatedValue(value: amountPassedBackToUserInfo)
}
现在,您需要在设置了delegate的类中实现此委托方法。
这里设置了UserInfoViewController
类委托,因此您需要实现其委托方法
extension UserInfoViewController: AddSubtractMoneyDelegate {
func calculatedValue(value: Double) {
//set label here
}
}
答案 2 :(得分:0)
如果你不支持委托(面向协议),你可以简单地浏览下面的代码。它只适用于两个类
但这不是一个好习惯 了解主要使用的,灵活的和可重复使用的编码方法的协议,闭包或通知中心广播。
<强> 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)
}
}
如果你很擅长,你可以使用协议..协议坚持要求一个类强制实现一个方法,使代码更可重用和独立。
在Above方法中,我们在执行segue时将当前viewcontroller(UserInfoViewController)的实例传递给下一个viewcontroller(AddSubtractMoney),因此我们可以访问 UserInfoViewController 中的函数的任何属性来自 AddSubtractMoney 。因此,很容易将数据从AddSubtractMoney传递到 - &gt; UserInfoViewController
答案 3 :(得分:0)
您还可以使用unwind segue传回数据。