ios - 未选择日期时如何重置内联 iOS UIDatePicker
问题描述
使用新的内联 UIDatePicker(在 iOS 14 中引入)时。当没有选择日期时,如何将日历重置为当前日期。
运行以下命令时,如果您选择了另一个日期,显示的日历将重置为当前日期:
self.datePicker.setDate(Date(), animated: true)
但是,如果您创建一个新的内联 UIDatePicker 并开始滚动月份,则在用户选择特定日期之前,运行同一行代码不会更新视图。
解决方案
这很好奇...
我的猜测是,当使用较旧的“滚轮”日期选择器样式时,当滚轮停止滚动时会选择一个新日期......没有办法从选定的日期“滚动离开”。
我的第二个猜测是这个问题可能会在未来的 iOS 更新中被改变(“修复”)。
无论如何,这是一种解决方法...
- 获取今天的日期
- 从选择器中获取选定的日期
- 如果它们相同,则用户可能滚动了月/年,所以
- 在“今天”上加一天
- 将选择器设置为“明天”(动画)
- 进行异步调用以将选择器设置为“今天”
- 如果日期不同,只需将选择器设置为“今天”(动画)
我只是对此进行了快速测试,因此您需要对其进行彻底测试。并且可能会添加一些额外的检查 - 例如如果日历在显示选择器时翻到午夜会发生什么;如果“今天”是本月的最后一天,它看起来如何;等等
// 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)
}
}
}
推荐阅读
- apache-kafka - Apache Heron 中的 Kafka 集成
- php - 如何防止在处理时选择行?
- python - 给定 4 点,如何从 pytorch/torchvision 中的图像中裁剪出四边形?
- angular - 当我返回相同的路线时,重用来自 api 的数据,角度 6
- jquery - 光滑滑块的自定义滚动导航
- jenkins - 从 Jenkins 电子邮件插件发送的加密 URL
- python - 从 falcon 中的参数化路由路径解析 uuid
- web - 在互联网上不同网络上的两个浏览器之间建立 Web RTC 连接时,我应该自己做 NAT 吗?
- iis - URL 重写在 azure 中的虚拟机上消失
- android - 如何使用改造将json响应添加到android中的微调器中?