TLDR: How to remove the swipe/pan gesture recognizer for UISegmentedControl on iOS 13?
Hi, on iOS 13, lots changed with UISegmentedControl. Mostly, the changes were
I upgraded @Aystub's answer. You can only allow UITapGestureRecogniger to select a segment.
class NoSwipeSegmentedControl: UISegmentedControl {
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if(gestureRecognizer.isKind(of: UITapGestureRecognizer.self)){
return false
}else{
return true
}
}
}
I have a similar setup (UISegmentedControl
inside a UIScrollView
bc it's too long and the client didn't want to compress the content to fit). This worked for me (Built on Xcode 11.1):
class NoSwipeSegmentedControl: UISegmentedControl {
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
Then set the class of my UISegmentedControl
to that. In my app this only prevents the swipe-to-select gesture on UISegmentedControl
objects embedded within a UIScrollView
. If it is not in a UIScrollView
nothing behaves any differently. Which makes sense because gestureRecognizerShouldBegin()
returns true
by default. So why this allows the UIScrollView
to take priority on the swipe gesture, I have no idea. But hope it helps.
Using this code allows the segmented control to still be swiped UNLESS it's embedded in a UIScrollView
. This is the smallest tradeoff in functionality in my opinion
final class NoSwipeSegmentedControl: UISegmentedControl {
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
guard type(of: gestureRecognizer).description() != "UIScrollViewPanGestureRecognizer" else {
return true
}
return super.gestureRecognizerShouldBegin(gestureRecognizer)
}
}