Search code examples
iosswiftuidatepicker

Is it possible to format a UIDatePicker?


I wonder if it is possible to format a UIDatePicker?

I would like to have weekdays before the dates as string, like "Monday 01.01.2018". I have seen this many times but I have not found anything.

Currently only the date is displayed without weekday before it.

I searched everywhere but found no answer.


Solution

  • If you’re showing just date and want to see day of the week, too, you may have to implement your own UIPickerView.

    For example, this creates a single-component picker. And, because depending upon where you live, 01.02.2019 might be interpreted as January 2nd or February 1st, I might suggest a localized format like EEEMMMdyyyy which is concise, localized, and unambiguous:

    class ViewController: UIViewController {
    
        @IBOutlet weak var pickerView: UIPickerView!
    
        private var startDate: Date!
        private var endDate: Date!
    
        private let formatter: DateFormatter = {
            let formatter = DateFormatter()
            formatter.setLocalizedDateFormatFromTemplate("EEEMMMdyyyy")
            return formatter
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            configurePicker()
        }
    
        func configurePicker() {
            // you can also hook up delegate and datasource in IB if you prefer
    
            pickerView.dataSource = self
            pickerView.delegate = self
    
            // set the range of dates to whatever is appropriate for your app
    
            let now = Date()
            startDate = now
            endDate = Calendar.current.date(byAdding: .year, value: 1, to: now)
        }
    
    }
    
    extension ViewController: UIPickerViewDataSource {
        func numberOfComponents(in pickerView: UIPickerView) -> Int {
            return 1
        }
    
        func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
            return Calendar.current.dateComponents([.day], from: startDate, to: endDate).day!
        }
    }
    
    extension ViewController: UIPickerViewDelegate {
        func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
            let date = Calendar.current.date(byAdding: .day, value: row, to: startDate)!
            return formatter.string(from: date)
        }
    
        func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
            let date = Calendar.current.date(byAdding: .day, value: row, to: startDate)!
            print(formatter.string(from: date))
        }
    }
    

    That yields (for a US user):

    enter image description here

    Now, if you want to have both your customized date string format and multiple components (e.g. day, month, and year as separate columns), it gets more confusing (because you have to do things like adjust the range of day values when you change the month), but the idea would be the same. Just create your own UIPickerView (or search the Interwebs for third party solutions).