【问题标题】:iOS 13 Segmented Control: Remove swipe gesture to select segmentiOS 13 分段控制:删除滑动手势以选择分段
【发布时间】:2020-01-30 07:05:49
【问题描述】:

TLDR:如何在 iOS 13 上移除 UISegmentedControl 的滑动/平移手势识别器?

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

在 iOS 13 上,使用 UISegmentedControls,除了触摸您要选择的片段之外,您现在还可以滑动/平移来更改所选片段。

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

这在 iOS 13 之前完美运行,现在,用户在拖动分段控件时无法滚动水平背景滚动视图,因为我假设滚动视图滚动识别器被新的滚动视图滑动以选择手势覆盖。

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

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

【问题讨论】:

  • 我根本没有研究过这个,但由于你没有运气寻找手势,也许没有使用它,它是使用来自UIResponder 的常用touchesXXX 方法实现的。您创建子类UISegmentedControl 并尝试覆盖touchesMoved。看看这是否能让你有所收获。

标签: ios swift uisegmentedcontrol ios13


【解决方案1】:

我有类似的设置(UISegmentedControlUIScrollView 内,因为它太长了,客户不想压缩内容以适应)。这对我有用(基于 Xcode 11.1 构建):

class NoSwipeSegmentedControl: UISegmentedControl {

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

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

【讨论】:

  • 这个简单而优雅的解决方案完美运行。问题解决了。确实应该有更好的文档来记录每次 iOS 更新对系统 UI 元素功能的更改。更好的是,像这样影响元素行为的属性应该能够在初始化期间或使用实例变量进行调整。非常感谢!
  • 答案是,通过覆盖gestureRecognizerShouldBegin,您允许滚动视图的平移手势识别器开始跟踪,这超过了分段控件的触摸处理。如果您调用super.gestureRecognizerShouldBegin(gestureRecognizer),您实际上可以看到它返回false(UISegmentedControl 拒绝接收到的手势)。
  • 此解决方案解决了 UISegmentedControl 上的滑动问题,但它使段难以选择。我是唯一一个受苦的人吗?
【解决方案2】:

我升级了@Aystub 的答案。您只能允许 UITapGestureRecogniger 选择一个段。

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

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

       }
}

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2013-10-15
      • 1970-01-01
      • 2015-10-05
      • 2020-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多