Dismiss a UIDatePicker using the addTarget function also dismisses it when selecting the year.

huangapple go评论69阅读模式
英文:

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。这严重依赖于UIDatePickerUICalendarView的实现更改。这很可能会在未来被破坏。

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:

Dismiss a UIDatePicker using the addTarget function also dismisses it when selecting the year.

But you don't want to do anything if the user changes the month/year in this state:

Dismiss a UIDatePicker using the addTarget function also dismisses it when selecting the year.

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.

huangapple
  • 本文由 发表于 2023年6月29日 12:42:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76578102.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定