user5647292
user5647292

Reputation:

Passing Data through segue in swift 2

Hey guys I need some help here with my code, please take a look to the images to see what I see, Im making a Tip Calculator Project in Swift and It must had a settings view where I select the default tip rate, I have some errors and I must fix that as soon as posible. I will really appreciate that some one corrects my code and test it. Pic 1 (MainViewController) pic 2 (MainStoryBoard) Below is the code of the two ViewControllers, I did not post the image of the Settings View Controller because the website does not let me post more than two links until I get more reputation.

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()
                }
            }

    }

Bellow is the code of the 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()

    }

Upvotes: 0

Views: 222

Answers (3)

UditS
UditS

Reputation: 1956

First, you have not implemented the tipPercentageChanged method in the ViewController class. Since tipPercentageChanged is a required method of the SettingDelegate protocol, you must implement this to conform to protocol.

Second, in prepareForSegue

        SettingsViewController.delegate = newValue

should actually be

        SettingsViewController.delegate = self

Since the delegate of SettingsViewController, will be ViewController.

So your updated code in ViewController should be

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)
}

Upvotes: 0

iRiziya
iRiziya

Reputation: 3245

Try this :

Replace your prepareForSegue function with :

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

and add tipPercentageChanged function

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

Hope it helps!

Upvotes: 0

Dharmesh Kheni
Dharmesh Kheni

Reputation: 71854

You have to add your delegate function into your ViewController class because your delegate function is not an optional.

Add this in your ViewController class:

func tipPercentageChanged(newValue : Double) {
    //your code
}

Upvotes: 1

Related Questions