在 UIDatePicker 中的小时和分钟之间添加冒号 (:) 并禁用默认值 AM/PM
Add Colon (:) between Hour and Minute & Disable default AM/PM in UIDatePicker
我正在尝试为 12-Hour 格式禁用 UIDatePicker
中的默认 AM/PM,并尝试在 Hour 和 Hour 之间添加冒号 (:)分钟。但是没有做到。
我在日期选择器中设置了以下代码以在 UIDatePicker
中设置时间。
self.datePicker.datePickerMode = .time
以上代码显示时间为 12 小时制,AM/PM。
见下图:
谁能帮我解决这个问题?
我相信 UIDatePicker 使用本地时间配置,所以我不建议您更改它。尽管如此,更改 dateTimePicker.locale
应该就足够了。
UIDatePicker
应按原样使用,无需自定义。你不应该弄乱它的观点,所以你可能会倒霉。如果您想要 UIDatePicker
不提供的行为,那么您可能需要使用 UIPickerView
创建您自己的控件。
引用文档:
Appearance
The appearance of UIDatePicker is not customizable.
为此,您将创建一个包含 2 个组件(小时和分钟)的选择器视图,并设置一个数据源,其中一个组件附加了一个冒号。请注意,组件也会滚动冒号,这可能不是您想要的。
您始终可以创建一个完全自定义的控件,但要让它完全按照您的要求进行操作需要大量工作,并且可能需要使用 CALayers
和 CAAnimation
,这两者相当先进
我认为最好的解决方案是简单地使用普通 UIPickerView
。这样你几乎可以控制一切。作为演示,我创建了这个全代码示例,它几乎可以满足您的要求:
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!))")
}
}
我会把这一切都放在故事板中,甚至放在 xib 中,以便在需要时可以重复使用。冒号的定位和样式可能需要一些工作,但这取决于您想要的设计。我只是为组件使用了 100k 的值来模拟无限滚动。至少应该为此定义一些常量。
通知hourValueAtIndex
和minuteValueAtIndex
;这些可以被操纵以使用几乎任何你需要的东西。要获得 0-23 小时,您只需使用 index%24
。但是,要使用它 1-24
需要做更多的工作:您会 return index%24 + 1
但是在构建日期时,您需要将 24 的值作为异常处理。您将使用 0 并添加额外的一天。但是您不能直接向组件添加额外的一天,因为您可能会在 7 月 32 日等情况下溢出。您确实需要在末尾添加一天:
selectedDate = calendarToUse.date(byAdding: DateComponents(day: 1), to: selectedDate)
我正在尝试为 12-Hour 格式禁用 UIDatePicker
中的默认 AM/PM,并尝试在 Hour 和 Hour 之间添加冒号 (:)分钟。但是没有做到。
我在日期选择器中设置了以下代码以在 UIDatePicker
中设置时间。
self.datePicker.datePickerMode = .time
以上代码显示时间为 12 小时制,AM/PM。
见下图:
谁能帮我解决这个问题?
我相信 UIDatePicker 使用本地时间配置,所以我不建议您更改它。尽管如此,更改 dateTimePicker.locale
应该就足够了。
UIDatePicker
应按原样使用,无需自定义。你不应该弄乱它的观点,所以你可能会倒霉。如果您想要 UIDatePicker
不提供的行为,那么您可能需要使用 UIPickerView
创建您自己的控件。
引用文档:
Appearance
The appearance of UIDatePicker is not customizable.
为此,您将创建一个包含 2 个组件(小时和分钟)的选择器视图,并设置一个数据源,其中一个组件附加了一个冒号。请注意,组件也会滚动冒号,这可能不是您想要的。
您始终可以创建一个完全自定义的控件,但要让它完全按照您的要求进行操作需要大量工作,并且可能需要使用 CALayers
和 CAAnimation
,这两者相当先进
我认为最好的解决方案是简单地使用普通 UIPickerView
。这样你几乎可以控制一切。作为演示,我创建了这个全代码示例,它几乎可以满足您的要求:
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!))")
}
}
我会把这一切都放在故事板中,甚至放在 xib 中,以便在需要时可以重复使用。冒号的定位和样式可能需要一些工作,但这取决于您想要的设计。我只是为组件使用了 100k 的值来模拟无限滚动。至少应该为此定义一些常量。
通知hourValueAtIndex
和minuteValueAtIndex
;这些可以被操纵以使用几乎任何你需要的东西。要获得 0-23 小时,您只需使用 index%24
。但是,要使用它 1-24
需要做更多的工作:您会 return index%24 + 1
但是在构建日期时,您需要将 24 的值作为异常处理。您将使用 0 并添加额外的一天。但是您不能直接向组件添加额外的一天,因为您可能会在 7 月 32 日等情况下溢出。您确实需要在末尾添加一天:
selectedDate = calendarToUse.date(byAdding: DateComponents(day: 1), to: selectedDate)