使用新的内联UIDatePicker(在iOS 14中引入(时。在未选择日期的情况下,如何将日历重置为当前日期。
运行以下操作时,当您选择另一个日期时,显示的日历将重置为当前日期:
self.datePicker.setDate(Date(), animated: true)
但是,如果创建一个新的内联UIDatePicker并开始滚动月份,则在用户选择特定日期之前,运行同一行代码不会更新视图。
这很奇怪。。。
我的猜测是,当使用较老的";"轮子";日期选择器样式,轮子停止滚动时会选择一个新日期。。。没有办法";滚动离开";从所选日期开始。
我的第二个猜测是,这个问题可能会在未来的iOS更新中得到改变("修复"(。
无论如何,这里有一个工作。。。
- 获取今天的日期
- 从选取器获取所选日期
- 如果它们相同,用户可能已经滚动了月份/年份,所以
- 将一天添加到";今天">
- 将选择器设置为"0";明天";(已设置动画(
- 进行异步调用以将选择器设置为"0";今天">
- 如果日期不相同,只需将选择器设置为";今天";(已设置动画(
我只做了一个快速测试,所以你需要彻底测试它。可能还需要添加一些额外的检查——比如当选择器显示时,如果日历在午夜滚动会发生什么;如果";今天";是一个月的最后一天;等
// get "today" date
let today = Date()
// get selected date
let pickerDate = self.datePicker.date
// are the dates the same day?
let todayIsSelected = Calendar.current.isDate(today, inSameDayAs:pickerDate)
if todayIsSelected {
// picker has today selected, but may have scrolled months...
// should never fail, but this unwraps the optional
guard let nextDay = Calendar.current.date(byAdding: .day, value: 1, to: today) else {
return
}
// animate to "tomorrow"
self.datePicker.setDate(nextDay, animated: true)
// async call to animate to "today"
DispatchQueue.main.async {
self.datePicker.setDate(today, animated: true)
}
} else {
// picker has a different date selected
// so just animate to "today"
self.datePicker.setDate(today, animated: true)
}
编辑-完整示例:
class ScratchVC: UIViewController {
let datePicker = UIDatePicker()
let btn = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
if #available(iOS 14.0, *) {
datePicker.preferredDatePickerStyle = .inline
} else {
// Fallback on earlier versions
}
btn.backgroundColor = .red
btn.setTitle("Go To Today", for: [])
btn.setTitleColor(.white, for: .normal)
btn.setTitleColor(.gray, for: .highlighted)
btn.translatesAutoresizingMaskIntoConstraints = false
datePicker.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(btn)
view.addSubview(datePicker)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
btn.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
btn.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0),
btn.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -40.0),
datePicker.widthAnchor.constraint(equalTo: g.widthAnchor, multiplier: 0.9),
datePicker.centerXAnchor.constraint(equalTo: g.centerXAnchor),
datePicker.centerYAnchor.constraint(equalTo: g.centerYAnchor),
])
btn.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)
}
@objc func didTap(_ sender: Any) {
// get "today" date
let today = Date()
// get selected date
let pickerDate = self.datePicker.date
// are the dates the same day?
let todayIsSelected = Calendar.current.isDate(today, inSameDayAs:pickerDate)
if todayIsSelected {
// picker has today selected, but may have scrolled months...
// should never fail, but this unwraps the optional
guard let nextDay = Calendar.current.date(byAdding: .day, value: 1, to: today) else {
return
}
// animate to "tomorrow"
self.datePicker.setDate(nextDay, animated: true)
// async call to animate to "today" - delay for 0.1 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: {
self.datePicker.setDate(today, animated: true)
})
} else {
// picker has a different date selected
// so just animate to "today"
self.datePicker.setDate(today, animated: true)
}
}
}