iOS 13 分段控件:删除滑动手势到 select 分段

iOS 13 Segmented Control: Remove swipe gesture to select segment

TLDR:如何在 iOS 13 上删除 UISegmentedControl 的 swipe/pan 手势识别器?

您好,在 iOS 13,UISegmentedControl 发生了很多变化。大多数情况下,这些变化是基于外观的。但是还有另一个功能更改正在弄乱我的应用程序。

在 iOS 13 上,使用 UISegmentedControls,您现在可以 swipe/pan 更改 selected 段,此外还可以触摸您想要 select 的段。

在我的应用程序中,我基本上在滚动视图中嵌入了一个 UISegmentedControl。 UISegmentedControl 太长,屏幕无法显示所有值,因此我创建了一个屏幕宽度的滚动视图,其内容宽度是 UISegmentedControl 的长度,并访问不可见的部分,用户滑动"scrollview" 和分段控制幻灯片。

这在 iOS 13 之前一直有效,现在,用户在拖动分段控件时无法滚动水平背景滚动视图,因为我假设滚动视图滚动识别器被新滚动视图覆盖滑动到 select 手势。

我什至尝试递归地删除 UISegmentedControl 及其所有子视图的所有手势识别器,并且滑动以更改 selection 手势仍然有效...我被卡住了。

谢谢,如果问题不清楚请告诉我

我有一个类似的设置(UISegmentedControl inside a UIScrollView bc 它太长了,客户不想压缩内容以适应)。这对我有用(基于 Xcode 11.1):

class NoSwipeSegmentedControl: UISegmentedControl {

    override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}

然后将我的 UISegmentedControl 的 class 设置为那个。在我的应用程序中,这只会阻止 UIScrollView 中嵌入的 UISegmentedControl 对象上的滑动到 select 手势。如果它不在 UIScrollView 中,则没有任何不同的行为。这是有道理的,因为默认情况下 gestureRecognizerShouldBegin() returns true。所以 为什么 这允许 UIScrollView 优先于滑动手势,我不知道。但希望它能有所帮助。

我升级了@Aystub 的回答。您只能允许 UITapGestureRecogniger select 一个片段。

class NoSwipeSegmentedControl: UISegmentedControl {
        override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {

            if(gestureRecognizer.isKind(of: UITapGestureRecognizer.self)){
                return false
            }else{
                return true
            }

       }
}

使用此代码允许分段控件仍然可以滑动,除非它嵌入 UIScrollView。在我看来,这是功能上最小的权衡

final class NoSwipeSegmentedControl: UISegmentedControl {

    override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        guard type(of: gestureRecognizer).description() != "UIScrollViewPanGestureRecognizer" else {
            return true
        }
        return super.gestureRecognizerShouldBegin(gestureRecognizer)
    }

}