通过 Segue 传递数据和一些错误

Posted

技术标签:

【中文标题】通过 Segue 传递数据和一些错误【英文标题】:Passing Data Through Segue & some errors 【发布时间】:2015-12-13 04:04:53 【问题描述】:

大家好,我需要有人帮我完成我的应用程序,我需要在 12 月 15 日之前完成它。我正在 Swift2 中制作一个小费计算器项目,它必须有一个设置视图,我可以在其中选择默认小费率。我在传递数据时遇到了一些问题,当我选择默认小费百分比时,它不会在视图控制器中更改,而且我想让应用程序在我关闭应用程序并重新打开时记住默认费率。我将非常感谢有人更正我的代码并对其进行测试。我是新手,下面是两个 ViewController 的代码和 Main.Storyboard 的屏幕截图 (Image 1) (ViewController Screenshot) 对不起,我的英语不好,不是我的母语

视图控制器

import UIKit

class ViewController: UIViewController 
//Inputs
@IBOutlet weak var amountTextField: UITextField!
//Labels
@IBOutlet weak var TipPercentageLabel: UILabel!
@IBOutlet weak var numberOfPersonLabel: UILabel!
@IBOutlet weak var tipAmountLabel: UILabel!
@IBOutlet weak var totalBillLabel: UILabel!
@IBOutlet weak var billPerPersonLabel: UILabel!
//Slider & Stepper
@IBOutlet weak var tipSlider: UISlider!
@IBOutlet weak var personsStepper: UIStepper!
//Variables
var tipPercentage = 0.20
var numberOfPerson:Int = 1
let numberFormatter:NSNumberFormatter = NSNumberFormatter()



override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    tipAmountLabel.text = "$0.00"
    totalBillLabel.text = "Bill Total"
    billPerPersonLabel.text = "$0.00"
    TipPercentageLabel.text =  "20.0%"
    numberOfPersonLabel.text = "1"
    self.amountTextField.becomeFirstResponder()


override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.

func setupContainer() 


    tipSlider.minimumValue = 0
    tipSlider.maximumValue = 100
    tipSlider.value = 20
    tipSlider.addTarget(self, action: "sliderTipChanged:", forControlEvents: .ValueChanged)

    personsStepper.minimumValue = 1
    personsStepper.maximumValue = 30
    personsStepper.value = 1
    personsStepper.addTarget(self, action: "sliderPersonChanged:", forControlEvents: .ValueChanged)

    amountTextField.text = ""

    refreshCalculation()


@IBAction func OnEditingFieldBill(sender: AnyObject) 
    refreshCalculation()

func refreshCalculation() 
    numberFormatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
    if let amount = numberFormatter.numberFromString(amountTextField.text!) as? Double 

        let tipAmount = amount * tipPercentage
        let totalBill = amount + tipAmount
        let billPerPerson = totalBill / Double(numberOfPerson)
        numberFormatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
        tipAmountLabel.text = numberFormatter.stringFromNumber(tipAmount)
        totalBillLabel.text = numberFormatter.stringFromNumber(totalBill)
        billPerPersonLabel.text = numberFormatter.stringFromNumber(billPerPerson)

     else 

        tipAmountLabel.text = "-"
        totalBillLabel.text = "-"
        billPerPersonLabel.text = "-"
    

    numberFormatter.numberStyle = NSNumberFormatterStyle.PercentStyle
    numberFormatter.minimumFractionDigits = 1
    numberFormatter.maximumFractionDigits = 1
    TipPercentageLabel.text = self.numberFormatter.stringFromNumber(tipPercentage)

    numberOfPersonLabel.text = "\(numberOfPerson)"


@IBAction func sliderTipChanged(sender: AnyObject) 
    tipPercentage = Double(round(tipSlider.value)) / 100
    refreshCalculation()

@IBAction func StepperPersonChanged(sender: AnyObject) 
    numberOfPerson = Int(round(personsStepper.value))
    refreshCalculation()

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
    if let id = segue.identifier 
        if id == "show settings" 
            if let SettingsViewController = segue.destinationViewController as? SettingsViewController 

            
        
    





设置视图控制器

import UIKit

class SettingsViewController: UIViewController 
@IBOutlet weak var tipControl: UISegmentedControl!
var tipRates:Double?

override func viewDidLoad() 
    super.viewDidLoad()

    // Do any additional setup after loading the view.


override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.

@IBAction func DefaultRate(sender: AnyObject) 
    var tipRate = [5, 10, 15, 20, 25, 30]
    var tipRates = Double(tipRate[tipControl.selectedSegmentIndex])

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
    if let id = segue.identifier 
        if id == "goBackToViewController" 
            if let ViewController = segue.destinationViewController as? ViewController 
                if let tip = tipRates 
                    ViewController.tipPercentage = tip/100
                
            
        

【问题讨论】:

【参考方案1】:

---- 从 cmets 编辑 ----

我认为它没有按您希望的那样更新的原因是由于此行的一个小错误。

var tipRates = Double(tipRate[tipControl.selectedSegmentIndex])

在 UISegmentedControl 的 DefaultRate 操作函数内部

使用 var 是对相同变量名的重新声明,因此您试图在 prepareForSegue 中传递的是一个空变量。

这个函数应该改成:

@IBAction func DefaultRate(sender: AnyObject) 
var tipRate = [5, 10, 15, 20, 25, 30]
tipRates = Double(tipRate[tipControl.selectedSegmentIndex])

希望这现在可以解决错误。

---- 结束编辑 ----

从我在 viewController 的 viewDidLoad 函数中可以看到,您正在设置提示标签,而不是根据变量 var tipPercentage 更新值。

TipPercentageLabel.text =  "20.0%"

将值显示设置为始终为 20.0%,您可以在此处使用。

var tipDisplay = tipPercentage * 100    
TipPercentageLabel.text = "\(tipDisplay)%"

这应该会更新标签中显示的值,但是您永远不会调用其他函数来重新计算金额等。

因此你也应该调用

func setupContainer()

func refreshCalculation()

在您的 ViewDidLoad() 中。

关于在应用关闭时记住默认值,您应该考虑使用 NSUserDefaults

Some information regarding NSUserDefaults can be found here,它解释了实现少量保存的数据,并且可以在您的情况下非常简单地实现。

【讨论】:

感谢您的支持,我在哪里写 var tipDisplay = tipPercentage * 100 TipPercentageLabel.text = "(tipDisplay)%" ? 您可以在 ViewController 的 ViewDidLoad 函数中将 TipPercentageLabel.text = "20.0%" 替换为 var tipDisplay = tipPercentage * 100 TipPercentageLabel.text = "(tipDisplay)%",因此它并不总是显示“ 20.0%" 加载时,它将显示您的 tipPercentage 变量的值。 知道了,我需要把 func setupContair 或 refreshCalculation 放在哪里? 您还应该在 ViewDidLoad 中调用其中一个,否则在用户更改文本之前它们不会被更新。由于您希望在显示视图后更新值,为此您可以使用 ViewDidLoad() 函数。 我按照你说的尝试了,但是当我在设置中更改小费百分比并返回 ViewController 时,它并没有改变。

以上是关于通过 Segue 传递数据和一些错误的主要内容,如果未能解决你的问题,请参考以下文章

通过 Segue 传递数据(swift 2)

在 swift 2 中通过 segue 传递数据

通过 segue 在视图控制器之间传递数据

通过 navigationController 使用 segue 传递数据

通过 unwind segue 传递数据

与 segue 一起传递数据