Reputation: 5823
I'm trying to disable default AM/PM in UIDatePicker
for 12-Hour format and also try to add colon (:) between Hour and Minute. But failed to do it.
I have set following code in date picker to set time in UIDatePicker
.
self.datePicker.datePickerMode = .time
Above code display time in 12-Hour format with AM / PM.
See following image:
Could anyone help me to fix this issue?
Upvotes: 0
Views: 1511
Reputation: 16774
I think your best solution is to simply use a normal UIPickerView
. This way you can control pretty much everything. As demonstration I created this all-in-code example which should nearly do what you seem to want:
class ViewController: UIViewController {
private let pickerView: UIPickerView = UIPickerView(frame: CGRect(x: 0.0, y: 300.0, width: 100.0, height: 300.0))
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(pickerView)
pickerView.dataSource = self
pickerView.delegate = self
pickerView.reloadAllComponents()
pickerView.selectRow(50000, inComponent: 0, animated: false)
pickerView.selectRow(50000, inComponent: 1, animated: false)
view.addSubview({
let label = UILabel(frame: .zero)
label.text = ":"
label.sizeToFit()
label.center = pickerView.center
label.isUserInteractionEnabled = false
return label
}())
}
}
extension ViewController: UIPickerViewDataSource, UIPickerViewDelegate {
private func hourValueAtIndex(index: Int) -> Int {
return index%12
}
private func minuteValueAtIndex(index: Int) -> Int {
return index%60
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return 100000
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
switch component {
case 0: return String(hourValueAtIndex(index: row))
case 1: return String(minuteValueAtIndex(index: row))
default: return ""
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let calendarToUse = Calendar.autoupdatingCurrent
var components = calendarToUse.dateComponents([.year, .month, .day], from: Date())
components.hour = hourValueAtIndex(index: pickerView.selectedRow(inComponent: 0))
components.minute = minuteValueAtIndex(index: pickerView.selectedRow(inComponent: 1))
let selectedDate = calendarToUse.date(from: components)
print("Selected new time (in UTC): \(selectedDate!)")
let formatter = DateFormatter()
formatter.calendar = calendarToUse
formatter.dateStyle = .short
formatter.timeStyle = .short
print("Selected new time (local): \(formatter.string(from: selectedDate!))")
}
}
I would put this all in storyboard or even in xib to have it reusable if needed. The positioning and styling of colon may need some work but this depends on what designs you want. I just used a 100k value for components to mimic infinite scroll. At least some constant should have been defined for that.
Notice hourValueAtIndex
and minuteValueAtIndex
; those can be manipulated to use pretty much anything you need. To have it 0-23 hours you would simply use index%24
. To have it 1-24
would need a bit more work though: You would return index%24 + 1
but when constructing a date you would need to handle the value of 24 as exception. You would use a 0 and add an extra day. But you can not add an extra day directly to components because you can then overflow for situations like 32nd of July. You do need to use add a day at the end:
selectedDate = calendarToUse.date(byAdding: DateComponents(day: 1), to: selectedDate)
Upvotes: 1
Reputation: 131408
UIDatePicker
is meant to be used as-is, without customizing it. You're not supposed to mess with it's views, so you might be out of luck. If you want behavior that a UIDatePicker
doesn't provide then you might need to create your own control using a UIPickerView
.
To quote the docs:
Appearance
The appearance of UIDatePicker is not customizable.
To do that, you'd create a picker view with 2 components, hour and minute, and set up a data source where one of the components has a colon appended to it. Note that the components will scroll the colons as well, which probably isn't exactly what you want.
You could always create a completely custom control, but getting it to do exactly what you want would be a lot of work, and would probably involve using CALayers
and CAAnimation
, both of which are fairly advanced
Upvotes: 0
Reputation: 759
I believe UIDatePicker uses the local time configuration, so I wouldn't recommend you to change it. Still, changing dateTimePicker.locale
should be enough.
Upvotes: 0