无法在 iOS 14 内联 DatePicker 中点击天数
Unable to Tap Days in iOS 14 inline DatePicker
我正在尝试创建一个 expandable/collapsible 日期选择器(类似于 Apple 在“设置”应用的“日期和时间”部分中的日期选择器)。我有一个 table 视图,可以将按钮作为其 table 单元格之一。该按钮显示当前选择的日期作为其标题。点击该按钮将在带有新 iOS 14 inline
日期选择器的按钮下方添加一个 table 单元格。
我面临的问题是,我可以通过更改月份和年份来与日期选择器进行交互,但是当我点击不同的日期时,所选日期并没有改变。我在 valueChanged
上添加了一个目标,当我更改月份和年份时会触发选择器方法,但当我选择不同的日期时不会。
我在 Whosebug 上看到有类似的问题,但不知为何被 OP 删除了。
包含日期选择器的 table 单元格很简单。我正在从它自己的 xib 中取出单元格,而 xib 只包含一个带有日期选择器的视图。我没有设置日期选择器单元格的高度,只是使用 UITableView.automaticDimension 来获取 self-sizing 单元格。我还查看了视图层次结构,日期选择器前面没有任何内容,因此应该将触摸发送到日期选择器。
还有其他人遇到过这个问题吗?
我遇到了同样的问题,我这边的问题是我如何在单元格内添加选择器。
检查你在做 self.contentView addSubview:
而不是 self addSubview
。
刚遇到同样的问题,我的日历最初工作正常但最终停止工作,UIDatePicker 在通过主视图中的情节提要添加的 UIView 中。
一切正常,我可以点击月份和年份并左右滑动月份。但是当试图点击一天时什么也不会发生。无法进行新的选择。
在我的例子中,它背后的原因是在我的主视图中添加了一个 tapGesture 来隐藏键盘。这使得日历日无法选择。
(https://i.stack.imgur.com/k4AKF.jpg)
好吧,我找到了一个变通办法,似乎允许在背景视图上进行点击手势,并且日历仍然有效;这个想法是在日历视图周围添加 4 个矩形视图,并将您的点击手势添加到这 4 个视图。
将选择器背景视图(我称为我的 datePickerBGView)添加到您的主视图,然后将您的 UIDatePicker(我称为我的选择器)添加到该背景视图并为两个视图分配相同的中心点:
picker.center = datePickerBGView.center
然后调用这个函数:
func addDismissGesture() {
//Work around because with the .inline date picker style tap gestures on the background view interfere with the day selection action on the picker's calendar view
let leftDismissActionTap = UITapGestureRecognizer(target: self, action: #selector(dismissCalendar))
let rightDismissActionTap = UITapGestureRecognizer(target: self, action: #selector(dismissCalendar))
let topDismissActionTap = UITapGestureRecognizer(target: self, action: #selector(dismissCalendar))
let bottomDismissActionTap = UITapGestureRecognizer(target: self, action: #selector(dismissCalendar))
let leftDismissArea = UIView()
let rightDismissArea = UIView()
let topDismissArea = UIView()
let bottomDismissArea = UIView()
leftDismissArea.frame = CGRect(x: 0, y: 0, width: picker.frame.minX - view.frame.minX, height: view.frame.height)
rightDismissArea.frame = CGRect(x: picker.frame.maxX, y: 0, width: view.frame.maxX - picker.frame.maxX, height: view.frame.height)
topDismissArea.frame = CGRect(x: leftDismissArea.frame.maxX, y: 0, width: rightDismissArea.frame.minX - leftDismissArea.frame.maxX, height: picker.frame.minY - view.frame.minY)
bottomDismissArea.frame = CGRect(x: leftDismissArea.frame.maxX, y: picker.frame.maxY, width:rightDismissArea.frame.minX - leftDismissArea.frame.maxX, height: view.frame.maxY - picker.frame.maxY)
datePickerBGView.addSubview(leftDismissArea)
datePickerBGView.addSubview(rightDismissArea)
datePickerBGView.addSubview(topDismissArea)
datePickerBGView.addSubview(bottomDismissArea)
leftDismissArea.addGestureRecognizer(leftDismissActionTap)
rightDismissArea.addGestureRecognizer(rightDismissActionTap)
topDismissArea.addGestureRecognizer(topDismissActionTap)
bottomDismissArea.addGestureRecognizer(bottomDismissActionTap)
leftDismissArea.backgroundColor = UIColor.black.withAlphaComponent(0.3)
rightDismissArea.backgroundColor = UIColor.black.withAlphaComponent(0.3)
topDismissArea.backgroundColor = UIColor.black.withAlphaComponent(0.3)
bottomDismissArea.backgroundColor = UIColor.black.withAlphaComponent(0.3)
datePickerBGView.bringSubviewToFront(picker)
}
我遇到了同样的问题。在我的例子中,问题出在 UITapGestureRecognizer 中,我添加它来隐藏键盘。
这段代码解决了我的问题:
tapGesture.cancelsTouchesInView = false
在我的例子中,我有一个在背景中带有遮罩的弹出式 datepickerView,我希望 datepickerView 在我单击背景时消失。所以我在后台添加了 UITapGestureRecognizer。添加手势后我无法select日期选择器中的日期
感谢@Сергій Насінник,此代码解决了我的问题:
tapGesture.cancelsTouchesInView = false
import UIKit
import SnapKit
class PopUpDatePickerView: UIView {
let contentView = UIView()
let datePicker = UIDatePicker()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .black.withAlphaComponent(0.4)
contentView.backgroundColor = .white
contentView.layer.cornerRadius = 16
addSubview(contentView)
contentView.snp.makeConstraints { make in
make.bottom.equalTo(self.safeAreaLayoutGuide).offset(-10)
make.left.right.equalToSuperview().inset(5)
}
datePicker.tintColor = .black
contentView.addSubview(datePicker)
datePicker.snp.makeConstraints { make in
make.edges.equalToSuperview().inset(20)
}
if #available(iOS 14.0, *) {
datePicker.preferredDatePickerStyle = .inline
}
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapHandler(_:)))
tapGesture.cancelsTouchesInView = false
addGestureRecognizer(tapGesture)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func tapHandler(_ sender: UITapGestureRecognizer) {
guard
!self.contentView.frame.contains(sender.location(in: self)) else {
return
}
removeFromSuperview()
}
}
我正在尝试创建一个 expandable/collapsible 日期选择器(类似于 Apple 在“设置”应用的“日期和时间”部分中的日期选择器)。我有一个 table 视图,可以将按钮作为其 table 单元格之一。该按钮显示当前选择的日期作为其标题。点击该按钮将在带有新 iOS 14 inline
日期选择器的按钮下方添加一个 table 单元格。
我面临的问题是,我可以通过更改月份和年份来与日期选择器进行交互,但是当我点击不同的日期时,所选日期并没有改变。我在 valueChanged
上添加了一个目标,当我更改月份和年份时会触发选择器方法,但当我选择不同的日期时不会。
我在 Whosebug 上看到有类似的问题,但不知为何被 OP 删除了。
包含日期选择器的 table 单元格很简单。我正在从它自己的 xib 中取出单元格,而 xib 只包含一个带有日期选择器的视图。我没有设置日期选择器单元格的高度,只是使用 UITableView.automaticDimension 来获取 self-sizing 单元格。我还查看了视图层次结构,日期选择器前面没有任何内容,因此应该将触摸发送到日期选择器。
还有其他人遇到过这个问题吗?
我遇到了同样的问题,我这边的问题是我如何在单元格内添加选择器。
检查你在做 self.contentView addSubview:
而不是 self addSubview
。
刚遇到同样的问题,我的日历最初工作正常但最终停止工作,UIDatePicker 在通过主视图中的情节提要添加的 UIView 中。
一切正常,我可以点击月份和年份并左右滑动月份。但是当试图点击一天时什么也不会发生。无法进行新的选择。
在我的例子中,它背后的原因是在我的主视图中添加了一个 tapGesture 来隐藏键盘。这使得日历日无法选择。
(https://i.stack.imgur.com/k4AKF.jpg)
好吧,我找到了一个变通办法,似乎允许在背景视图上进行点击手势,并且日历仍然有效;这个想法是在日历视图周围添加 4 个矩形视图,并将您的点击手势添加到这 4 个视图。
将选择器背景视图(我称为我的 datePickerBGView)添加到您的主视图,然后将您的 UIDatePicker(我称为我的选择器)添加到该背景视图并为两个视图分配相同的中心点:
picker.center = datePickerBGView.center
然后调用这个函数:
func addDismissGesture() {
//Work around because with the .inline date picker style tap gestures on the background view interfere with the day selection action on the picker's calendar view
let leftDismissActionTap = UITapGestureRecognizer(target: self, action: #selector(dismissCalendar))
let rightDismissActionTap = UITapGestureRecognizer(target: self, action: #selector(dismissCalendar))
let topDismissActionTap = UITapGestureRecognizer(target: self, action: #selector(dismissCalendar))
let bottomDismissActionTap = UITapGestureRecognizer(target: self, action: #selector(dismissCalendar))
let leftDismissArea = UIView()
let rightDismissArea = UIView()
let topDismissArea = UIView()
let bottomDismissArea = UIView()
leftDismissArea.frame = CGRect(x: 0, y: 0, width: picker.frame.minX - view.frame.minX, height: view.frame.height)
rightDismissArea.frame = CGRect(x: picker.frame.maxX, y: 0, width: view.frame.maxX - picker.frame.maxX, height: view.frame.height)
topDismissArea.frame = CGRect(x: leftDismissArea.frame.maxX, y: 0, width: rightDismissArea.frame.minX - leftDismissArea.frame.maxX, height: picker.frame.minY - view.frame.minY)
bottomDismissArea.frame = CGRect(x: leftDismissArea.frame.maxX, y: picker.frame.maxY, width:rightDismissArea.frame.minX - leftDismissArea.frame.maxX, height: view.frame.maxY - picker.frame.maxY)
datePickerBGView.addSubview(leftDismissArea)
datePickerBGView.addSubview(rightDismissArea)
datePickerBGView.addSubview(topDismissArea)
datePickerBGView.addSubview(bottomDismissArea)
leftDismissArea.addGestureRecognizer(leftDismissActionTap)
rightDismissArea.addGestureRecognizer(rightDismissActionTap)
topDismissArea.addGestureRecognizer(topDismissActionTap)
bottomDismissArea.addGestureRecognizer(bottomDismissActionTap)
leftDismissArea.backgroundColor = UIColor.black.withAlphaComponent(0.3)
rightDismissArea.backgroundColor = UIColor.black.withAlphaComponent(0.3)
topDismissArea.backgroundColor = UIColor.black.withAlphaComponent(0.3)
bottomDismissArea.backgroundColor = UIColor.black.withAlphaComponent(0.3)
datePickerBGView.bringSubviewToFront(picker)
}
我遇到了同样的问题。在我的例子中,问题出在 UITapGestureRecognizer 中,我添加它来隐藏键盘。
这段代码解决了我的问题:
tapGesture.cancelsTouchesInView = false
在我的例子中,我有一个在背景中带有遮罩的弹出式 datepickerView,我希望 datepickerView 在我单击背景时消失。所以我在后台添加了 UITapGestureRecognizer。添加手势后我无法select日期选择器中的日期
感谢@Сергій Насінник,此代码解决了我的问题:
tapGesture.cancelsTouchesInView = false
import UIKit
import SnapKit
class PopUpDatePickerView: UIView {
let contentView = UIView()
let datePicker = UIDatePicker()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .black.withAlphaComponent(0.4)
contentView.backgroundColor = .white
contentView.layer.cornerRadius = 16
addSubview(contentView)
contentView.snp.makeConstraints { make in
make.bottom.equalTo(self.safeAreaLayoutGuide).offset(-10)
make.left.right.equalToSuperview().inset(5)
}
datePicker.tintColor = .black
contentView.addSubview(datePicker)
datePicker.snp.makeConstraints { make in
make.edges.equalToSuperview().inset(20)
}
if #available(iOS 14.0, *) {
datePicker.preferredDatePickerStyle = .inline
}
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapHandler(_:)))
tapGesture.cancelsTouchesInView = false
addGestureRecognizer(tapGesture)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func tapHandler(_ sender: UITapGestureRecognizer) {
guard
!self.contentView.frame.contains(sender.location(in: self)) else {
return
}
removeFromSuperview()
}
}