UIDatePicker
UIDatePicker is a UIKit control that allows users to select dates, times, or both using a spinning wheel or compact interface. It is a subclass of UIControl and is commonly used in forms or settings to input date and time values. This document covers the key properties, methods, and usage of UIDatePicker, along with examples and best practices.
Overview of UIDatePicker
UIDatePicker provides a user-friendly interface for selecting date and time values. It supports various modes (e.g., date, time, date and time, countdown timer) and styles (e.g., wheels, compact, inline) introduced in iOS 13.4 and later. The picker is highly customizable, allowing developers to set date ranges, time zones, and formatting options.
Creating a UIDatePicker
You can create a UIDatePicker programmatically or via Interface Builder (storyboards/xibs).
Programmatic Example:
import UIKit
let datePicker = UIDatePicker()
datePicker.datePickerMode = .date
datePicker.addTarget(self, action: #selector(dateChanged(_:)), for: .valueChanged)
view.addSubview(datePicker)Key Properties of UIDatePicker
Below are the most commonly used properties of UIDatePicker:
| Property | Type | Description |
|---|---|---|
datePickerMode | UIDatePicker.Mode | The mode of the picker (e.g., .date, .time, .dateAndTime, .countDownTimer). |
preferredDatePickerStyle | UIDatePickerStyle | The visual style of the picker (e.g., .automatic, .wheels, .compact, .inline) (iOS 13.4+). |
date | Date | The currently selected date. |
minimumDate | Date? | The earliest selectable date. |
maximumDate | Date? | The latest selectable date. |
countDownDuration | TimeInterval | The duration for countdown timer mode (in seconds). |
minuteInterval | Int | The interval for minute selection (e.g., 1, 5, 15). |
timeZone | TimeZone? | The time zone for the picker’s date. |
locale | Locale? | The locale for formatting the date and time. |
calendar | Calendar | The calendar used for date calculations. |
Date Picker Modes
.date: Selects a date (e.g., June 5, 2025)..time: Selects a time (e.g., 4:14 PM)..dateAndTime: Selects both date and time..countDownTimer: Selects a duration for a countdown timer (e.g., 30 minutes).
Date Picker Styles (iOS 13.4+)
.automatic: Adapts to the context (default)..wheels: Traditional spinning wheel interface..compact: Compact interface with a tappable field that opens a calendar or clock (iOS 13.4+)..inline: Inline calendar or clock view (iOS 13.4+).
Example: Configuring Properties:
datePicker.datePickerMode = .dateAndTime
datePicker.preferredDatePickerStyle = .compact
datePicker.minimumDate = Date()
datePicker.maximumDate = Calendar.current.date(byAdding: .year, value: 1, to: Date())
datePicker.minuteInterval = 5Key Methods of UIDatePicker
UIDatePicker inherits methods from UIControl and provides methods to manage date selection:
| Method | Description |
|---|---|
setDate(_:animated:) | Sets the selected date, optionally animating the change. |
Example: Setting a Date:
datePicker.setDate(Date(), animated: true)Handling User Interaction
To respond to date changes, add a target-action for the .valueChanged event.
Example:
datePicker.addTarget(self, action: #selector(dateChanged(_:)), for: .valueChanged)
@objc func dateChanged(_ sender: UIDatePicker) {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
print("Selected date: \(formatter.string(from: sender.date))")
}Customizing UIDatePicker
Setting Date Ranges
Use minimumDate and maximumDate to restrict the selectable dates.
Example:
let today = Date()
datePicker.minimumDate = today
datePicker.maximumDate = Calendar.current.date(byAdding: .month, value: 6, to: today)Countdown Timer Mode
Use .countDownTimer mode to select a duration, and set countDownDuration to get or set the value.
Example:
datePicker.datePickerMode = .countDownTimer
datePicker.countDownDuration = 3600 // 1 hourLocalization
Set locale and calendar to support different regions and date formats.
Example:
datePicker.locale = Locale(identifier: "en_GB")
datePicker.calendar = Calendar(identifier: .gregorian)Appearance
Customize the picker’s appearance using tintColor or backgroundColor.
Example:
datePicker.tintColor = .systemBlue
datePicker.backgroundColor = .systemGray6Using UIDatePicker in Forms
UIDatePicker is often used as an input view for a UITextField or embedded in a form.
Example: Using with UITextField:
let textField = UITextField()
textField.placeholder = "Select Date"
textField.inputView = datePicker
// Add toolbar for dismissing
let toolbar = UIToolbar()
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(dismissPicker))
toolbar.setItems([UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil), doneButton], animated: false)
textField.inputAccessoryView = toolbar
@objc func dismissPicker() {
textField.resignFirstResponder()
}Best Practices
Choose Appropriate Style: Use
.compactor.inlinefor modern apps (iOS 13.4+); fall back to.wheelsfor older iOS versions.Support Accessibility: Set
accessibilityLabelandaccessibilityTraitsfor VoiceOver.swiftdatePicker.accessibilityLabel = "Date selector" datePicker.accessibilityTraits = .adjustableUse Auto Layout: Set
translatesAutoresizingMaskIntoConstraints = falseand use constraints (e.g., with SnapKit).Format Output: Use
DateFormatterto display the selected date in a user-friendly format.Test Across Regions: Verify behavior with different locales, calendars, and time zones.
Handle Dynamic Changes: Update
minimumDateormaximumDatedynamically if needed (e.g., based on user input).
Troubleshooting
- Picker Not Responding: Ensure the target-action is set for
.valueChangedand the picker is added to the view hierarchy. - Incorrect Date Format: Check
localeandcalendarsettings; useDateFormatterfor display. - Style Not Applied: Verify iOS version compatibility for
.compactor.inlinestyles. - Accessibility Issues: Test with VoiceOver to ensure proper feedback.
- Layout Issues: Ensure constraints provide enough space, especially for
.inlinestyle.
Example: Complete UIDatePicker Setup
import UIKit
import SnapKit
class ViewController: UIViewController {
let datePicker = UIDatePicker()
let dateLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
// Configure date picker
datePicker.datePickerMode = .date
datePicker.preferredDatePickerStyle = .compact
datePicker.minimumDate = Date()
datePicker.maximumDate = Calendar.current.date(byAdding: .year, value: 1, to: Date())
datePicker.addTarget(self, action: #selector(dateChanged(_:)), for: .valueChanged)
datePicker.accessibilityLabel = "Date selector"
// Configure label
let formatter = DateFormatter()
formatter.dateStyle = .medium
dateLabel.text = "Selected: \(formatter.string(from: datePicker.date))"
dateLabel.textAlignment = .center
view.addSubview(datePicker)
view.addSubview(dateLabel)
// Auto Layout with SnapKit
datePicker.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(view.safeAreaLayoutGuide).offset(20)
}
dateLabel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(datePicker.snp.bottom).offset(20)
}
}
@objc func dateChanged(_ sender: UIDatePicker) {
let formatter = DateFormatter()
formatter.dateStyle = .medium
dateLabel.text = "Selected: \(formatter.string(from: sender.date))"
}
}