kupilot
kupilot

Reputation: 504

Swift datepicker in popovercontroller not updating the correct label

In my app i have added 2 labels and 2 buttons, the buttons are hooked to a function that pops a datepicker in popovercontroller, when user select a date the corresponding label should change.

Everything work except the labels are updated together, what I want is update only the relevant label, i.e. when when button1 is pressed label1 should recieve datepicker date and vice versa.

Here is my code:

import UIKit

class PopoverTestVC: UIViewController, UIPopoverPresentationControllerDelegate {

@IBOutlet weak var dateLabel: UILabel!
@IBOutlet weak var dateLabel2: UILabel!

@IBOutlet weak var selectButton: UIButton!
@IBOutlet weak var selectButton2: UIButton!

@IBOutlet var datePicker: UIDatePicker!

var dateString = ""

let vc = UIViewController()

override func viewDidLoad() {
    super.viewDidLoad()

    datePicker.timeZone = NSTimeZone(abbreviation: "GMT")
    //datePicker.addTarget(self, action: Selector("datePicked:"), forControlEvents: UIControlEvents.ValueChanged)
}

func datePicked(sender: UIDatePicker) {
    let dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "dd MMM yyyy HH:mm"
    dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT")
    dateLabel.text = dateFormatter.stringFromDate(datePicker.date)

}

func datePicked2(sender: UIDatePicker) {
    let dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "dd MMM yyyy HH:mm"
    dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT")
    dateLabel2.text = dateFormatter.stringFromDate(datePicker.date)

}

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

@IBAction func popUp(sender: UIButton)
{
    let fr = datePicker.frame
    vc.view.frame = fr
    vc.view.addSubview(datePicker!)
    vc.view.backgroundColor = UIColor.greenColor()
    vc.preferredContentSize = datePicker.frame.size
    vc.modalPresentationStyle = UIModalPresentationStyle.Popover

    if sender == selectButton
    {
        datePicker.addTarget(self, action: Selector("datePicked:"), forControlEvents: UIControlEvents.ValueChanged)
    }
    else if sender == selectButton2
    {
        datePicker.addTarget(self, action: Selector("datePicked2:"), forControlEvents: UIControlEvents.ValueChanged)
    }

    let popOverPC = vc.popoverPresentationController
    vc.popoverPresentationController?.sourceRect = sender.frame
    vc.popoverPresentationController?.sourceView = view
    popOverPC!.permittedArrowDirections = UIPopoverArrowDirection.Any
    popOverPC!.delegate = self
    presentViewController(vc, animated: true, completion: nil)
}

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle
{
    return UIModalPresentationStyle.None
}
}

Appreciate any help or suggestion to do that in better way as the app might have several outlets that use the same datepicker.

Upvotes: 0

Views: 581

Answers (1)

Peter Todd
Peter Todd

Reputation: 8651

I'd move your date picker to a custom class (this also lets you use a xib to do some cool design stuff) call this from your view controller setting a var to the button that called the date picker. Create a protocol in the date picker and implement the delegate in the parent view controller populating whatever labels you require based on the button that called the date picker.

For example, in my app I have several text fields that must contain dates. When the user begins to edit the text field I launch a custom popover from textFieldShouldBeginEditing and assign the text field to a var.
The parent view controller is set as the delegate to a protocol in my custom date picker:

// MARK: - Textfield delegate
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
    textField.backgroundColor = UIColor.whiteColor()

    if (textField.tag == 500 || textField.tag == 501)
    {
        activeTextField = textField
        let vc = BGSDatePickerVC(nibName: "BGSDatePickerVC", bundle: nil)
        vc.modalPresentationStyle = UIModalPresentationStyle.Popover
        if textField.tag == 500{
            vc.popoverPresentationController?.sourceView = viewMarkerFromDate
        }else
        {
            vc.popoverPresentationController?.sourceView = viewMarkerToDate
        }

        vc.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.Up
        vc.preferredContentSize = CGSizeMake(vc.view.frame.width, vc.view.frame.height)
        vc.delegate = self
        self.presentViewController(vc, animated: true, completion: nil)
        return false
    }
    return true       
}

The protocol in my custom date picker popover:

protocol BGSDatePickerVCProtocol
{
    func bgsDatePickerUse(date: NSDate, strDate: String)
}

class BGSDatePickerVC: UIViewController {
    var delegate:BGSDatePickerVCProtocol! = nil

and the implementation in the calling view controller:

// MARK: - Delegates
// MARK: BGSDatePickerVCProtocol

func bgsDatePickerUse(date: NSDate, strDate: String)
{
    if activeTextField.tag == 500
    {
        dateSelectedFrom = date
    }
    if activeTextField.tag == 501
    {
        dateSelectedTo = date
    }
    activeTextField.text = strDate
}

Upvotes: 1

Related Questions