如何确定DatePicker当前是否正在旋转/滚动?我已经尝试了几乎所有的东西,并在这里查看了所有的答案,但没有一个是正确的或有效的。
基本上,我想在旋转时禁用按钮,然后在停止时启用相同的按钮。
谢谢!
答案 0 :(得分:0)
我想做同样的事情,所以围绕UIControl和UIDatePicker的类转储进行了讨论。正如maddy
在评论部分中所述,似乎没有任何作用。
好吧,我确实发现这是某种实现方式-在短时间内(例如50毫秒)截取选择器视图的屏幕截图,并对前后的图像进行比较以查看其变化。当然,这似乎需要做很多工作!
因此,我尝试了多种方法(iOS13),发现可以使用手势识别器来检测何时首次触摸选择器,以及何时更新UIDatePicker自己的识别器。这通常使我能够检测到用户交互何时可能结束。
然后,我可以等待动作方法发出信号,表明旋转停止了。嗯,但是如果用户只是移动了一个轮子然后放回去,会发生什么?如果新日期与旧日期相同,则没有操作方法。所以我要做的是使用延迟的调度工作项,两秒钟后裁定微调器停止。
final class DHDatePicker: UIDatePicker, UIGestureRecognizerDelegate {
var isSpinning = false { didSet { print("IS SPINNING", isSpinning) } }
private var didAddGR = false
private var cancelBlock = DispatchWorkItem(block: {})
override init(frame: CGRect) {
super.init(frame: frame)
let gr = UISwipeGestureRecognizer()
gr.direction = [.up, .down]
gr.delegate = self
self.addGestureRecognizer(gr)
self.addTarget(self, action: #selector(dateChanged(_:)), for: .primaryActionTriggered)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func gr(_ gr: UISwipeGestureRecognizer) {
switch gr.state {
case .ended, .cancelled, .failed:
cancelBlock.cancel()
cancelBlock = DispatchWorkItem(block: {
if self.isSpinning {
self.isSpinning = false
}
})
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0, execute: cancelBlock)
print("GR ENDED")
default:
print("WTF")
break
}
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
isSpinning = true
return true
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if didAddGR == false {
didAddGR = true
print("DP Attach to Other GR")
otherGestureRecognizer.addTarget(self, action: #selector(gr(_:)))
}
return false
}
@objc func dateChanged(_ sender: UIDatePicker) {
print("DP ActionMethod")
cancelBlock.cancel()
isSpinning = false
}
}