Search code examples
swiftuidatepicker

Using 24 Hour DatePicker in Swift


I'm struggling to set the datepicker to only allow time and a 24 hour format in Swift, any ideas how to do this?

Thanks


Solution

  • The OP says he is trying to recreate this answer in Swift. That answer is a kludge (it depends on Danish locale using 24-hour format, not on actually solving the problem), but here's how you would do that in Swift:

    var datePicker = UIDatePicker() // Although you probably have an IBOutlet
    datePicker.datePickerMode = UIDatePickerMode.Time
    datePicker.locale = NSLocale(localeIdentifier: "da_DK")
    

    but this is a kludge - roll your own UIPicker!

    UPDATE The OP said that rolling your own is "hassle" - it's actually really easy - here's one simple way to do it (though a better way would be to subclass UIPickerView)...

    import UIKit
    
    class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    
        @IBOutlet weak var myDatePicker: UIPickerView!
        private var calendar = Calendar.autoupdatingCurrent
    
        override func viewDidLoad() {
            super.viewDidLoad()
            self.time = Date() // updates the picker to "now"
        }
    
        // MARK: UIPickerViewDataSource
        func numberOfComponents(in: UIPickerView) -> Int { return 2 }
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            if component == 0 { // Hours
                return 24
            }
            return 12 // five minute intervals
        }
    
        // MARK: UIPickerViewDelegate
        func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
            if component == 0 { // Hours
                return String(format: "%02d", row)
            }
            return String(format: "%02d", row * 5)
        }
        func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
            print("picker changed, selected \(self.time)")
        }
    
        // MARK: Getting & setting the time
        var time: Date {
            get {
                let unitFlags: Calendar.Unit = [.year, .day, .hour, .minute, .second]
                var components = self.calendar.components(unitFlags, from: Date())
                components.hour = self.myDatePicker.selectedRow(inComponent: 0)
                components.minute = self.myDatePicker.selectedRow(inComponent: 1) * 5
                components.second = 0
                if let date = self.calendar.date(from: components) {
                    return date
                }
                return Date() // shouldn't get here
            }
            set {
                var components = self.calendar.components([.hour, .minute], from: newValue)
                if let hour = components.hour, let minute = components.minute {
                    self.myDatePicker.selectRow(hour, inComponent: 0, animated: true)
                    self.myDatePicker.selectRow(minute / 5, inComponent: 1, animated: true)
                }
            }
        }
    }