自定义 UIControl 滑块在嵌入 iOS13 模态 viewController 时不起作用

Custom UIControl slider doesn't work when embedded in iOS13 modal viewController

当我将自定义 UIControl 嵌入 ViewController 中并以新的 iOS13 自动样式模态呈现时,只要平移手势移动超过几个点,就会调用 touchesCancelled

本机UIKitUISlider不这样做。您可以在 automatic 样式模态 ViewController 中平移 UISlider 没有问题。

UIScrollView 具有 touchesShouldCancel(in view: UIView),您可以在其中强制它允许在指定视图中进行触摸,但我在文档中找不到任何关于这种新模式呈现样式的内容。

您可以在 UIControl 上实现 UIGestureRecognizerDelegategestureRecognizerShouldBeginUIPanGestureRecognizer[=16= 的 return false ]

//MARK: UIGestureRecognizerDelegate
extension RangeSlider: UIGestureRecognizerDelegate {
    public override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return !(gestureRecognizer is UIPanGestureRecognizer)
    }
}

如果您在 UITableViewCell 内使用范围滑块,这将捕获来自 UIGestureRecognizerDelegate 的事件。虽然很奇怪 gestureRecognizerShouldBegin 也没有在这里触发。不是最优的,但也许其他人在注意到这一点后有了新想法。

extension RangeTableViewCell {
override func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    // Very hackish but there is no other option I've found for now
    // Consider using a custom modal presentation style and transition
    // this gesture actually makes the range slider call cancelTracking so we disable it
    if otherGestureRecognizer is UIPanGestureRecognizer && otherGestureRecognizer.view?.className.contains("UIDropShadowView") ?? false {
        otherGestureRecognizer.isEnabled = false
    }
    return false
}

}

PS:我尝试将上面的函数用作 return otherGestureRecognizer is UIPanGestureRecognizer;也没用

问题似乎在于使用 UIControl 函数 touchesBegantouchesMovedtouchesEndedtouchesCancelled 的覆盖来观察拖动。这些触摸事件无法像 UIGestureRecognizerDelegate 那样被拦截,因此无法阻止模态拖动强制 touchesCancelled.

答案似乎是:不要使用UIControl触摸事件方法。相反,-像其他答案一样表明有效-使用 UIPanGestureRecognizer 和委托方法 gestureRecognizerShouldBegin.

一直以来的麻烦是尝试按照 Apple 文档所说的那样使用 UIControl。