ToolBar done button action does not work on UIDatePicker

9.3k views Asked by At

I set done and cancel button on my UIDatePicker within a toolbar programmatically. However, I could not detect click actions for done and cancel buttons. I could not find the cause of the issue. Here is my code:

@IBAction func btnDueDate_Click(sender: UIButton)
{
    var toolBar = UIToolbar()
    toolBar.barStyle = UIBarStyle.Default
    toolBar.translucent = true
    toolBar.tintColor = UIColor(red: 92/255, green: 216/255, blue: 255/255, alpha: 1)
    toolBar.sizeToFit()

    var doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("Done_Click"))
    var spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
    var cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("Cancel_Click"))

    toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
    toolBar.userInteractionEnabled = true

    self.datePicker.addSubview(toolBar)
    self.datePicker.hidden = false
}

func Done_Click()
{
    var dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "dd-MM-yyyy"
    self.btnDueDate.setTitle(dateFormatter.stringFromDate(self.datePicker.date), forState: UIControlState.Normal)
}

func Cancel_Click()
{
    self.datePicker.hidden = true
}

Could you help me about what am I doing wrong ?

Thank you for your answers

Best regards

Solved: Thank u for your help, I've solved the problem by editting the code line below:

self.view.addSubview(toolBar)

When I add the toolbar as a subview of self.view, not as a subview of self.datePicker, It works fine.

3

There are 3 answers

0
Kumuluzz On

The reason why your code isn't working is because the UIToolbar is overlapping the UIDatePicker and the picker is receiving all of the inputs.

I would suggest for you to use the property inputAccessoryView and assign the toolbar to this, but unfortunately, this is a read-only property for both the UIButton and UIDatePicker


A work-around which many people are using is to use a UITextField and set the inputView to a UIDatePicker and the inputAccessoryView to a UIToolbar. I've made a small example underneath that you can try out.

//
//  ViewController.swift
//  DatePickerWithToolbar
//
//  Created by Stefan Veis Pennerup on 10/06/15.
//  Copyright (c) 2015 Kumuluzz. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var tvDueDate: UITextField!
    var datePicker = UIDatePicker()

    override func viewDidLoad() {
        setupDatePicker()
    }

    func setupDatePicker() {
        // Sets up the "button"
        tvDueDate.text = "Pick a due date"
        tvDueDate.textAlignment = .Center

        // Removes the indicator of the UITextField
        tvDueDate.tintColor = UIColor.clearColor()

        // Specifies intput type
        datePicker.datePickerMode = .Date

        // Creates the toolbar
        let toolBar = UIToolbar()
        toolBar.barStyle = .Default
        toolBar.translucent = true
        toolBar.tintColor = UIColor(red: 92/255, green: 216/255, blue: 255/255, alpha: 1)
        toolBar.sizeToFit()

        // Adds the buttons
        var doneButton = UIBarButtonItem(title: "Done", style: .Plain, target: self, action: "doneClick")
        var spaceButton = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target: nil, action: nil)
        var cancelButton = UIBarButtonItem(title: "Cancel", style: .Plain, target: self, action: "cancelClick")
        toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
        toolBar.userInteractionEnabled = true

        // Adds the toolbar to the view
        tvDueDate.inputView = datePicker
        tvDueDate.inputAccessoryView = toolBar
    }

    func doneClick() {
        var dateFormatter = NSDateFormatter()
        //dateFormatter.dateFormat = "dd-MM-yyyy"
        dateFormatter.dateStyle = .ShortStyle
        tvDueDate.text = dateFormatter.stringFromDate(datePicker.date)
        tvDueDate.resignFirstResponder()
    }

    func cancelClick() {
        tvDueDate.resignFirstResponder()
    }  
}
1
Puji Wahono On
dateFormatter.dateStyle = .ShortStyle
dateFormatter.dateFormat = "dd-MM-yyyy"

Note : to function dateformat under datesyle

0
MinnuKaAnae On

Showing UIDatePicker when UIButton pressed with Done button from this answer

var datePickerContainer = UIView()
let timePicker = UIDatePicker()

@IBAction func openTimePicker(sender: UIButton) {

    datePickerContainer.frame = CGRect(x: 0.0, y: (self.view.frame.height/2 + 30), width: self.view.frame.width, height: 250)
    datePickerContainer.backgroundColor = UIColor.white

    let doneButton = UIButton()
    doneButton.setTitle("Done", for: .normal)
    doneButton.setTitleColor(UIColor.blue, for: .normal)
    doneButton.addTarget(self, action: #selector(dismissPicker), for: UIControlEvents.touchUpInside)
    doneButton.frame = CGRect(x: 250.0, y: 5.0, width: 70.0, height: 40.0)
    datePickerContainer.addSubview(doneButton)

    timePicker.frame = CGRect(x: 0.0, y: 40.0, width: self.view.frame.width, height: 200.0)
    timePicker.datePickerMode = UIDatePickerMode.time
    timePicker.backgroundColor = UIColor.white
    timePicker.addTarget(self, action: #selector(CreateActivityViewController.startTimeDiveChanged), for: UIControlEvents.valueChanged)
    datePickerContainer.addSubview(timePicker)

    self.view.addSubview(datePickerContainer)
}

@objc func startTimeDiveChanged(sender: UIDatePicker) {
    let formatter = DateFormatter()
    formatter.timeStyle = .short
    expectedTimeBtn.setTitle(formatter.string(from: sender.date), for: .normal)
}

@objc func dismissPicker() {
    datePickerContainer.removeFromSuperview()

}