自定义 UIControl 滑块在嵌入 iOS13 模态 viewController 时不起作用
Custom UIControl slider doesn't work when embedded in iOS13 modal viewController
当我将自定义 UIControl 嵌入 ViewController 中并以新的 iOS13 自动样式模态呈现时,只要平移手势移动超过几个点,就会调用 touchesCancelled
。
本机UIKit
UISlider
不这样做。您可以在 automatic
样式模态 ViewController 中平移 UISlider 没有问题。
UIScrollView 具有 touchesShouldCancel(in view: UIView)
,您可以在其中强制它允许在指定视图中进行触摸,但我在文档中找不到任何关于这种新模式呈现样式的内容。
您可以在 UIControl
上实现 UIGestureRecognizerDelegate
的 gestureRecognizerShouldBegin
和 UIPanGestureRecognizer
[=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
函数 touchesBegan
、touchesMoved
、touchesEnded
和 touchesCancelled
的覆盖来观察拖动。这些触摸事件无法像 UIGestureRecognizerDelegate
那样被拦截,因此无法阻止模态拖动强制 touchesCancelled
.
答案似乎是:不要使用UIControl
触摸事件方法。相反,-像其他答案一样表明有效-使用 UIPanGestureRecognizer
和委托方法 gestureRecognizerShouldBegin
.
一直以来的麻烦是尝试按照 Apple 文档所说的那样使用 UIControl。
当我将自定义 UIControl 嵌入 ViewController 中并以新的 iOS13 自动样式模态呈现时,只要平移手势移动超过几个点,就会调用 touchesCancelled
。
本机UIKit
UISlider
不这样做。您可以在 automatic
样式模态 ViewController 中平移 UISlider 没有问题。
UIScrollView 具有 touchesShouldCancel(in view: UIView)
,您可以在其中强制它允许在指定视图中进行触摸,但我在文档中找不到任何关于这种新模式呈现样式的内容。
您可以在 UIControl
上实现 UIGestureRecognizerDelegate
的 gestureRecognizerShouldBegin
和 UIPanGestureRecognizer
[=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
函数 touchesBegan
、touchesMoved
、touchesEnded
和 touchesCancelled
的覆盖来观察拖动。这些触摸事件无法像 UIGestureRecognizerDelegate
那样被拦截,因此无法阻止模态拖动强制 touchesCancelled
.
答案似乎是:不要使用UIControl
触摸事件方法。相反,-像其他答案一样表明有效-使用 UIPanGestureRecognizer
和委托方法 gestureRecognizerShouldBegin
.
一直以来的麻烦是尝试按照 Apple 文档所说的那样使用 UIControl。