在 swift 2 中通过 segue 传递数据

Posted

技术标签:

【中文标题】在 swift 2 中通过 segue 传递数据【英文标题】:Passing Data through segue in swift 2 【发布时间】:2015-12-10 05:56:20 【问题描述】:

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

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 = newValue
            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()

    

【问题讨论】:

【参考方案1】:

您必须将您的委托函数添加到您的 ViewController 类中,因为您的委托函数不是可选的。

将此添加到您的 ViewController 类中:

func tipPercentageChanged(newValue : Double) 
    //your code

【讨论】:

对不起,我没听懂,我很新,这只是我的第一个项目。 这可能会对您有所帮助:developer.apple.com/library/ios/documentation/Swift/Conceptual/… 谢谢你的帮助我真的很感激,但我没看懂,这超出了我的水平 你能分享示例项目吗? 是的,我可以,我该怎么做?【参考方案2】:

首先,您还没有在 ViewController 类中实现 tipPercentageChanged 方法。由于 tipPercentageChanged 是 SettingDelegate 协议的必需方法,因此您必须实现它以符合协议。

第二,在prepareForSegue

        SettingsViewController.delegate = newValue

应该是

        SettingsViewController.delegate = self

既然是 SettingsViewController 的委托,那就是 ViewController。

所以你在 ViewController 中更新的代码应该是

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


func tipPercentageChanged(newValue: Double) 

    // What you want to do, when Percentage is changed
    // Update tipSlider
    tipSlider.value = Float(newValue)

【讨论】:

谢谢,但是我的代码看起来会怎样。我是新来的。所以我需要在函数下面写什么。当百分比改变时,我想要滑块并将值设置为该百分比。我该怎么写呢? 我按照你说的做了,但我有一些问题,如果你能再次帮助我,我将不胜感激 好的,我会尽力的..您遇到什么问题? 如何在设置视图中更改tipRate 时同步提示滑块,例如我在设置视图中选择15% 并立即将提示滑块设置为中间。 检查更新的代码。此外,您可能需要考虑将tipPercentageChanged 中的newValue 类型更改为Float。这将避免键入 Cast 的需要。【参考方案3】:

试试这个:

将您的 prepareForSegue 函数替换为:

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


并添加tipPercentageChanged函数

func tipPercentageChanged(newValue: Double) 
     TipPercentageLabel.text =  "\(newValue)%" //reset label value
     tipSlider.value = newValue //reset slider value too

希望对你有帮助!

【讨论】:

它说我可以将值类型 Double 分配给 Float

以上是关于在 swift 2 中通过 segue 传递数据的主要内容,如果未能解决你的问题,请参考以下文章

Swift:将数据传递给 segue

Swift segue 不会将数据传递给旧的 ViewController

通过 Segue 将数据传递给新的 ViewController

在函数内将数据传递给 segue.destination 的问题

如何在没有 segue 的情况下在 Swift 3 中将数据从 VC 传递到另一个?

Xcode中多个Segues中通过UITableViews传递数据(三个Segues)