为 segue 做准备,传递数据

Posted

技术标签:

【中文标题】为 segue 做准备,传递数据【英文标题】:Prepare for segue, passing data 【发布时间】:2015-12-10 13:25:46 【问题描述】:

大家好,我的代码需要一些帮助,请查看图片以了解我看到的内容。我正在用 Swift 制作一个小费计算器项目,我必须有一个设置视图,在其中选择默认小费率。我有一些错误,我必须尽快解决。我将非常感谢有人更正我的代码并对其进行测试。下面是两个 ViewController 的代码,我没有发布 Settings View Controller 的图像,因为网站不允许我发布两个以上的链接,直到我获得更多的声誉。

Xcode 中的错误:


故事板:检查图像我在第一行有一些错误。

import UIKit

class ViewController: UIViewController, SettingDelegate 
// 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 : Double = NSUserDefaults.standardUserDefaults().doubleForKey("DefaultTipRate") ?? 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: UISlider) 

    tipPercentage = Double(round(tipSlider.value)) / 100
    refreshCalculation()



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

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
    if let SettingsViewController = segue.destinationViewController as?SettingsViewController 
        SettingsViewController.delegate = self
        refreshCalculation()
            
        


下面的SettingsViewController:

import UIKit
protocol SettingDelegate 
func tipPercentageChanged(newValue : Double)

class SettingsViewController: UIViewController 
var destName : String!
var delegate : SettingDelegate?
@IBOutlet weak var tipControl: UISegmentedControl!

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 tipRates = [0.05, 0.10, 0.15, 0.20, 0.25, 0.30]
    let tipRate = tipRates[tipControl.selectedSegmentIndex]

    delegate?.tipPercentageChanged(tipRate)

    NSUserDefaults.standardUserDefaults().setDouble(tipRate, forKey: "DefaultTipRate")
    NSUserDefaults.standardUserDefaults().synchronize()



/

【问题讨论】:

所以,您要做的是将选择提示从 SettingsView 获取到“主”视图。对吗? 为了符合SettingDelegate协议,ViewController必须实现tipPercentageChanged方法。 您应该使用导航控制器以便自动获得后退按钮,或者您应该使用展开转场。执行常规 segue 以返回到您的主 ViewController 会创建它的新实例,而不是返回到原始实例。如果您反复执行此操作,您将耗尽内存并导致应用崩溃。 是的@adolfosrs 这就是我想要做的 你的错误是什么? 【参考方案1】:

对于您的第一个错误:

viewController符合协议时,它需要实现协议实现的方法。在你的情况下,定义你应该有

func tipPercentageChanged(newValue : Double) 
    //save the new value here

第一个错误应该会消失。

看起来您正在使用modal 转换呈现SettingsViewController,因此您可以使用

self.dismissViewControllerAnimated(true, completion: )

【讨论】:

以上是关于为 segue 做准备,传递数据的主要内容,如果未能解决你的问题,请参考以下文章

Segue 为 segue 做准备的特定值

UICollectionView 控制器和在准备 Segue 中传递 CloudKit 数据

尝试使用 segue 将数据从一个视图控制器传递到另一个视图控制器

如何快速在UITabBar之间传递数据

使用 Sender 为 Swift 中的 Segue 做准备

将数据从模态 segue 传递给父级