英文:
Dismissing a UIDatePicker By AddTarget function also dismiss while selecting year
问题
我正在尝试使用addTarget
函数在选择日期时关闭日期选择器。当我选择年份时,它在我选择日期之前关闭,当我首先选择日期时,我无法选择年份。我实际想要的是,在选择年份时它不应该关闭,只有在我选择日期时才关闭。是否有可能使用UIDatePicker实现这个问题的解决方案?
以下是您的代码:
let datePicker: UIDatePicker = {
let date = UIDatePicker()
date.datePickerMode = .date
date.preferredDatePickerStyle = .compact
date.tintColor = UIColor(red: 83/255, green: 176/255, blue: 184/255, alpha: 1)
return date
}()
func config() {
datePicker.addTarget(self, action: #selector(selectButtonAction), for: .primaryActionTriggered)
}
@objc func selectButtonAction() {
// 代码逻辑...
dismiss(animated: true)
}
您可以尝试在selectButtonAction
方法中添加逻辑,以仅在选择日期时执行dismiss
操作,而不是在选择年份时执行。这可能需要根据日期选择器的值来判断何时执行dismiss
。
英文:
I am trying to dismiss a datePicker during selection of date by addTarget function. After when I select year it dismiss before I select date and when I select the date first I cannot select year. what I actually want is, during selection of year it shouldn't dismiss. It should dismiss when I select date. Is there any possible solution for this with using UIdatePicker ?
This is my code
let datePicker : UIDatePicker = {
let date = UIDatePicker()
date.datePickerMode = .date
date.preferredDatePickerStyle = .compact
date.tintColor = UIColor(red: 83/255, green: 176/255, blue: 184/255, alpha: 1)
return date
}()
func config() {
datePicker.addTarget(self, action: #selector(selectButtonAction), for: .primaryActionTriggered)
}
@objc func selectButtonAction() {
// code logic ...
dismiss(animated: true)
}
答案1
得分: 0
如果我理解正确,您希望在用户在此状态下选择日期时关闭当前的VC:
但是,如果用户在此状态下更改月份/年份,您不希望执行任何操作:
没有官方支持的方法可以做到这一点 - 您不应该以这种方式使用UIDatePicker
。
我建议添加一个“确定”按钮或类似的东西,让用户确认他们已经选择了日期。想象一下,如果用户在日历上误触并意外关闭了整个VC,那将非常令人沮丧。
如果您确实希望有这样的行为,我建议自己创建日期选择器。
也就是说,月份-年份选择器毕竟是一个UIView
,可以在视图层次结构中找到。经过一些逆向工程,该视图被称为_UICalendarMonthYearSelector
,截至iOS 16。
因此,在selectButtonAction
中,您可以尝试在视图层次结构中找到此视图,并且如果找到它,则不要dismiss
。这严重依赖于UIDatePicker
和UICalendarView
的实现更改。这很可能会在未来被破坏。
func findViewInViewHierarchy(root: UIView, target: AnyClass) -> UIView? {
if root.isKind(of: target) {
return root
}
for subview in root.subviews {
if let found = findViewInViewHierarchy(root: subview, target: target) {
return found
}
}
return nil
}
@objc func selectButtonAction() {
// 对于`.compact`样式的日期选择器,请使用`presentedViewController.view!`作为根视图
// 对于`.inline`样式的日期选择器,请使用日期选择器本身作为根视图
let monthYearSelector = findViewInViewHierarchy(root: presentedViewController.view!, target: NSClassFromString("_UICalendarMonthYearSelector")!)
if calendar == nil {
// 关闭...
}
}
如果您实际上想要关闭.compact
样式日期选择器显示的弹出窗口,而不是self
,请参阅我的此答案。
英文:
If I understand correctly, you want to dismiss the current VC when the user selects a date in this state:
But you don't want to do anything if the user changes the month/year in this state:
There is no officially supported way to do this - you are not supposed to use a UIDatePicker
in this way.
I suggest adding an "OK" button or something to that effect, to let the user confirm that they have selected a date. Think about the case of a user mis-taps on the calendar, and end up accidentally dismissing the whole VC. That's quite frustrating if you ask me.
If you really want a behaviour like this, I would suggest making your own date selector.
That said, the month-year selector is, after all, a UIView
, and can be found in the view hierarchy. After some reverse-engineering, that view is called _UICalendarMonthYearSelector
, as of iOS 16.
So theoretically, in selectButtonAction
, you can try to find this view in the hierarchy, and do not dismiss
if you found it. This is heavily subject to changes in the implementation of UIDatePicker
and UICalendarView
. This will probably break in the future.
func findViewInViewHierarchy(root: UIView, target: AnyClass) -> UIView? {
if root.isKind(of: target) {
return root
}
for subview in root.subviews {
if let found = findViewInViewHierarchy(root: subview, target: target) {
return found
}
}
return nil
}
@objc func selectButtonAction() {
// for .compact style date pickers, use presentedViewController.view! as the root
// for .inline style date pickers, use the date picker itself as the root
let monthYearSelector = findViewInViewHierarchy(root: presentedViewController.view!, target: NSClassFromString("_UICalendarMonthYearSelector")!)
if calendar == nil {
// dismiss...
}
}
If you actually wanted to dismiss the pop up that a .compact
style date picker shows, rather than self
, see this answer of mine.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论