在iOS 14中以编程方式打开UIDatePicker

hxzsmxv2  于 2022-09-19  发布在  iOS
关注(0)|答案(16)|浏览(254)

我有这个普通的UIDatePicker(对不起,它不是英文的,请忽略它):

但问题是,只有当我按下日期选择器时,它才会出现:

我想知道如何像第一张图片一样显示日期选择器(它用模糊效果覆盖了整个屏幕)只用代码,这样用户就不需要按日期选择器来显示日期选择器。谢谢。

dy2hfwbg

dy2hfwbg1#

您可以使用具有.compact样式的日期选取器,并在其顶部放置UILabel并赋予其背景颜色以将datePicker隐藏在其后面,并确保禁用标注用户交互然后您应该能够点击日期选取器,它将显示日期选取器的模式和更改的值您可以使用自己的日期格式化程序相应地设置标注的文本,您也可以同时在UIView中设置日期选取器和标注并使其裁剪到边界

cx6n0qe3

cx6n0qe32#

我也有同样的问题。我正在使用以下黑客攻击:

let datePicker = UIDatePicker(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
datePicker.preferredDatePickerStyle = .compact

// Removes Labels
datePicker.subviews.forEach({ B1a0a1b.subviews.forEach({ B1a0a1b.removeFromSuperview() }) })

然后,我只需将此日期选取器添加到一个视图的顶部,它应该会打开此弹出窗口。

yi0zb3m4

yi0zb3m43#

无法从代码中打开带有UIKit14UIDatePicker

  • UIDatePicker没有执行此操作的接口
  • UIKit不允许我们创建对UIKit有任何影响的UIEventsUITouch对象。
m3eecexj

m3eecexj4#

不幸的是,不可能以编程方式显示日期选择器弹出窗口,至少不能采用可能导致应用程序被拒绝的黑客手段:

  • UIDatePicker控件不公开可通过sendActions(for:)以编程方式触发的任何事件-allControlEvents返回空选项集
  • 在iOS上编程模拟用户点击是正式不可能的-没有公共API来实现这一点,所有的解决方法都意味着求助于私有API
  • 如果以上还不够,UIDatePicker的UI结构由私有类组成:

结论是,在目前的状态下,UIDatePicker用户界面只能通过用户交互进行控制。也许这种情况在未来会改变,例如UIButton的expose动作会触发与用户点击按钮时相同的行为,因此UIDatePicker可能会在未来公开此类动作。

kxeu7u2r

kxeu7u2r5#

我不知道这是否仍然有效,但您可以使用新的UIDatePicker的.inline样式。然后使用您自己的视图和动画来模仿.compact样式的DatePicker的外观。

let secondDatePicker = UIDatePicker()
secondDatePicker.preferredDatePickerStyle = .inline
self.view.addSubview(secondDatePicker)

secondDatePicker.translatesAutoresizingMaskIntoConstraints = false
secondDatePicker.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
secondDatePicker.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
46scxncf

46scxncf6#

更新:这在iOS 15上不再起作用。

@Amr Mohamed的答案很聪明,在日期选择器视图上放置了一个标签,但这也会导致在点击日期选择器视图时出现故障,当日期选择器VC动画显示时,您也可以看到日期选择器。

因此,我们需要“隐藏”日期选取器视图,但也要让它保持交互。(我们不能只使用isHidden = truealpha = 0,否则它不再可点击)

这是我在我的项目中所做的:

extension UIView {
    func loopDescendantViews(_ closure: (_ subView: UIView) -> Void) {
        for v in subviews {
            closure(v)
            v.loopDescendantViews(closure)
        }
    }
}

let datePicker = UIDatePicker()
datePicker.preferredDatePickerStyle = .compact
datePicker.loopDescendantViews {
    B1a0a1b.alpha = B1a0a1b is UIControl ? 1 : 0
}

然后,您可以将这个不可见的日期选择器放在您的标签/其他视图的顶部。一旦你点击标签(实际上点击了日期选择器),日期选择器VC就会显示动画。

dz6r00yl

dz6r00yl7#

您可以从情节提要中将日期选择器的首选样式设置为“内联”。通过这样做,您将直接获得直接选择日期的全屏。

以下是日期选择器如何查找首选的“紧凑型”样式(您已有的样式):

Vs“inline”(你要找的那个):

z9smfwbn

z9smfwbn8#

为了确保我们没有遗漏一些显而易见的东西,*.inline*样式显示完整的日历,而用户不需要单击日期或时间标签。有了这种能力,用户可以安排任何他们想要的关于显示日历和选定/默认日期等的行为。

vyswwuz2

vyswwuz29#

我认为唯一不麻烦的方法是创建一个新的视图控制器,在其中添加一个具有嵌入样式的UIDatePicker示例,然后以模式或弹出式的形式呈现控制器。

svmlkihl

svmlkihl10#

我使用这个扩展在UIDatePicker的每个子视图上设置clear颜色,然后按照其他人的建议使用UILabel

extension UIDatePicker {

  private func traverse(view: UIView) {
    for subview in view.subviews {
      self.traverse(view: subview)

      // Setting alpha to 0 disables userInteraction.
      subview.alpha = 0.02
    }
  }

  func paintClear() {
    self.traverse(view: self)
  }

}
y0u0uwnf

y0u0uwnf11#

好吧,我找到了一种方法,让它同时适用于iOS 14和iOS 15,但由于它读取的是层次结构,它可能会停止与任何即将发布的iOS版本一起工作:

// The callback from your tap gesture or whatever you use:
func handleTapOnView() {
    let datePickerGesture: UIGestureRecognizer? = {
        guard let compactView = datePicker.subviews.first else { return nil }
        // iOS 15
        if let dateLabel = compactView.subviews
                .first(where: { String(describing: type(of: B1a0a1b)).hasSuffix("DateLabel") }),
           let gesture = dateLabel.gestureRecognizers?.first {
            return gesture
        }
        // iOS 14
        if let gesture = compactView.gestureRecognizers?.last {
            return gesture
        }
        return nil
    }()
    datePickerGesture?.state = .ended
}

对于代码的‘iOS 15’部分,如果您想要聚焦于日期选择部分,则使用.hasSuffix("DateLabel"),而对于聚焦时间选择部分,则使用.hasSuffix("TimeLabel")

holgip5t

holgip5t12#

它可以切换到旧风格的日期选择器:

if (@available(iOS 13.4, *)) {
            [datePicker setPreferredDatePickerStyle:UIDatePickerStyleWheels];
        }
h79rfbju

h79rfbju13#

定义这些变量

var datePicker: UIDatePicker!
var datePickerConstraints = [NSLayoutConstraint]()
var blurEffectView: UIView!

然后创建函数showDatePicker(),您可以调用该函数来触发UIDatePicker的显示。首先,创建一个与他的父视图大小相同的子视图,并给它一个模糊的效果。然后将UIDatePicker作为子视图添加到模糊视图的顶部。

func showDatePicker() {
        datePicker = UIDatePicker()
        datePicker?.date = Date()
        datePicker?.locale = .current
        datePicker?.preferredDatePickerStyle = .inline
        datePicker?.addTarget(self, action: #selector(dateSet), for: .valueChanged)
        addDatePickerToSubview()
    }

    func addDatePickerToSubview() {
        guard let datePicker = datePicker else { return }
        // Give the background Blur Effect
        let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.regular)
        blurEffectView = UIVisualEffectView(effect: blurEffect)
        blurEffectView.frame = self.view.bounds
        blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        self.view.addSubview(blurEffectView)
        self.view.addSubview(datePicker)
        datePicker.translatesAutoresizingMaskIntoConstraints = false
        centerDatePicker()
        view.bringSubviewToFront(datePicker)
    }

    func centerDatePicker() {
        guard let datePicker = datePicker else { return }
        // Center the Date Picker
        datePickerConstraints.append(datePicker.centerYAnchor.constraint(equalTo: self.view.centerYAnchor))
        datePickerConstraints.append(datePicker.centerXAnchor.constraint(equalTo: self.view.centerXAnchor))
        NSLayoutConstraint.activate(datePickerConstraints)
    }

最后,一旦在UIDatePicker中选择了日期

@objc func dateSet() {
        // Get the date from the Date Picker and put it in a Text Field
        compactDatePicker.date = datePicker.date
        blurEffectView.removeFromSuperview()
        datePicker.removeFromSuperview()
    }

不完全确定模糊效果,因此希望有人可以在此解决方案的基础上进行改进。

7eumitmz

7eumitmz14#

日期选择器在iOSv14.0中进行了更改,在此之前它是一个内联滚轮。现在,在iOS v14.0中,您可以做的是告诉它是内联的,它将以内联的方式显示日历(没有弹出窗口):

if #available(iOS 14.0, *) {
     datePicker.preferredDatePickerStyle = UIDatePickerStyle.inline         
}

注:您可能需要固定帧大小,因为日期选择器在iOS 13(轮子)和iOS 14(日历)中看起来不同,因此您可能需要为版本13设置“Else”。

5tmbdcev

5tmbdcev15#

我猜你使用的是compact日期选择器样式,这是iOS14上的一个新功能。我认为你可以简单地使用‏‏‏‏的inline样式而不是compact来显示完整的日历用户界面。别忘了UIDatePicker只是一个UIView,所以你可以定制你的演示文稿来实现你想要的模糊效果。‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏

相关问题