Swift 在iOS 14中以编程方式打开UIDatePicker
我有一个普通的Swift 在iOS 14中以编程方式打开UIDatePicker,swift,uikit,uidatepicker,ios14,Swift,Uikit,Uidatepicker,Ios14,我有一个普通的UIDatePicker(很抱歉,它不是英文的,请忽略它): 但问题是,它只在我按下日期选择器时出现: 我想知道如何像第一幅图像中那样显示日期选择器(它用模糊效果覆盖了整个屏幕)只使用代码,这样用户就不需要按下日期选择器来显示日期选择器。谢谢。我猜您使用的是iOS 14上的一项新功能--紧凑型日期选择器样式。我认为你可以简单地使用使用inline样式而不是compact来显示完整的日历UI。不要忘记,UIDatePicker只是一个UIView,因此您可以自定义演示文稿
UIDatePicker
(很抱歉,它不是英文的,请忽略它):
但问题是,它只在我按下日期选择器时出现:
我想知道如何像第一幅图像中那样显示日期选择器(它用模糊效果覆盖了整个屏幕)只使用代码,这样用户就不需要按下日期选择器来显示日期选择器。谢谢。我猜您使用的是iOS 14上的一项新功能--
紧凑型
日期选择器样式。我认为你可以简单地使用使用inline
样式而不是compact
来显示完整的日历UI。不要忘记,UIDatePicker
只是一个UIView
,因此您可以自定义演示文稿以实现所需的模糊效果。 我也有同样的问题。我正在使用以下黑客:
let datePicker = UIDatePicker(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
datePicker.preferredDatePickerStyle = .compact
// Removes Labels
datePicker.subviews.forEach({ $0.subviews.forEach({ $0.removeFromSuperview() }) })
然后,我只需在视图顶部添加此日期选择器,该视图将打开此弹出窗口。不可能从代码内部用
UIKit14
打开UIDatePicker
没有用于执行此操作的APIUIDatePicker
不允许我们创建对UIKit
有任何影响的UIKit
或UIEvents
对象UITouch
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()
}
不完全确定模糊效果,因此希望有人能在此解决方案基础上进行构建。不幸的是,无法通过编程方式显示日期选择器弹出窗口,至少不能诉诸可能导致您的应用被拒绝的黑客手段:
- UIDatePicker控件不公开任何可以通过
sendActions(for:)
-allControlEvents
以编程方式触发的事件,返回空选项集
- 通过编程模拟用户点击在iOS上是不可能的-没有公共API来实现这一点,所有的解决方法都意味着求助于私有API
- 如果以上还不够,UIDatePicker的UI结构由私有类组成:
结论是,在当前状态下,UIDatePicker
UI只能通过用户交互进行控制。这可能会在将来发生变化,例如,UIButton
的expose actions用于触发与用户点击按钮时相同的行为,因此,UIDatePicker
可能会在将来公开此类操作。我不知道这是否仍然有效,但是您可以使用新UIDatePicker的.inline
样式。然后使用自己的视图和动画模拟.compact
样式中日期选择器的外观
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
如果要继续使用wheels格式,可以在故事板上将样式设置为wheels
或者使用这个代码
datePicker.preferredDatePickerStyle = .wheels
试试这个-
datePicker.preferredDatePickerStyle = .inline
您可以使用带有.compact
样式的日期选择器,并在其顶部放置UILabel
,并为其提供背景色,以隐藏其后面的日期选择器,并确保禁用标签用户交互,然后您应该能够点击日期选择器,它将显示模式,然后显示日期选择器的更改值。您可以使用自己的日期格式化程序相应地设置标签文本,您还可以在UIView
中同时使用datePicker和标签,并将其剪裁到边界我认为唯一的非黑客方法是创建一个新的视图控制器,在其中添加一个嵌入样式的UIDatePicker实例,然后以模式或弹出式显示控制器。@Amr Mohamed的答案很聪明,在日期选择器视图上添加了一个标签,但这也会导致在点击日期选择器视图时出现故障,当日期选择器vc设置动画时,您也可以看到日期选择器
因此,我们需要“隐藏”日期选择器视图,但也要让它保持交互式。(我们不能只使用ishiden=true
或alpha=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 {
$0.alpha = $0 is UIControl ? 1 : 0
}
然后,您可以将这个不可见的日期选择器放在标签/其他视图的顶部。点击标签(实际上点击了日期选择器)后,日期选择器vc将显示动画。切换到旧样式的日期选择器:
if (@available(iOS 13.4, *)) {
[datePicker setPreferredDatePickerStyle:UIDatePickerStyleWheels];
}
你是如何创建这个用户界面的?故事板?密码?你有出口吗?故事板,是的,我有出口。但是第一张图片中的菜单是在我按下紧凑菜单时生成的。你找到解决方案了吗?不,还没有。您可以使用yourPicker.becomeFirstResponder()
强制对象成为第一响应者。这应该或多或少模拟在日期字段上点击。是的,我知道。但是没有一种方法可以用代码打开紧凑型日期选择器,当用户关闭它时,它会变小?显示全屏选择器UI的触发器是什么动作?在UIMenuy中按一个项可以使用内联
样式的UI以编程方式显示全屏选择器,还有一个自定义视图来显示选定的日期。但是动画呢?谢谢你的建议,但我不会将其标记为已接受,因为它不会回答我所有的问题。用户仍然必须按下日期选择器才能打开它。我想要一个解决方案,而不是用户按下,我将只使用代码。我认为这是最接近实现此功能的解决方案。这对我不起作用。但是没有dateTextField
。