首页 > 解决方案 > 在其中一个页面中包含的 UISwitch 上开始触摸时禁用 UIPageViewController 滚动

问题描述

我有UIPageViewController一个页面是设置屏幕。在该屏幕上,可以UISwitch打开或关闭设置。

虽然我注意到很多UISwitch人像我一样点击 a 来切换它,但我观察到一些用户滑动 aUISwitch来切换它。

当它位于 a的一部分时,尝试滑动它UISwitch可能会导致问题,因为滑动开关可以开始滑动 ,就好像用户想要更改页面一样。UIViewControllerUIPageViewControllerUIPageViewController

这种行为感觉非常破碎和不一致。似乎如果用户触摸开关,但在滑动前短暂犹豫,触摸被注册UISwitch并按用户预期工作。但是,如果用户触摸UISwitch并立即开始滑动,则UIPageViewController改为获得触摸。UISwitch在接触与否之间似乎有一条非常细的界限(犹豫阈值) 。

你将如何解决这个问题?

下面是一个示例,首先通过简单的点击来切换UISwitch,然后显示一些尝试滑动UISwitch导致不一致结果的不同方法:

不一致的 uiswitch 行为


可能的解决方案和问题

我考虑解决此问题的一种方法是检测Settings UIViewController上任何位置的触摸,如果触摸开始于 框架中的某处UISwitch,请防止UIPageViewController滑动。

我担心的是,简单地禁用滑动UIPageViewController并不能保证触摸传递给UISwitch. 这意味着用户可能会尝试滑动UISwitch并且UIPageViewController不会滑动,但UISwitch也不会响应触摸,使其看起来仍然损坏且不一致。

为了开始探索这种可能的解决方案,我尝试通过覆盖如下touchesBegan方法来检测触摸:

override func touchesBegan(_ touches: Set<UITouch>,
                           with event: UIEvent?) {

    print("touchesBegan")

    super.touchesBegan(touches,
                       with: event)
}

我已经尝试在特定设置页面上以这种方式检测触摸UIPageViewControllerUIViewController没有被调用。我也尝试过设置view.isUserInteractionEnabled = true视图,以及不同 s 的不同组合truefalseUIViewController似乎仍然无法检测到触摸。

我还考虑过放弃UIPageViewController此应用程序的整个范例,并将设置屏幕改为模式,因为这将解决对这种复杂解决方案的需求,但UIPageViewController应用程序中的范例还有其他优点,所以我想要探索是否可以保留。最终,这似乎比奇怪的解决方法更好,但我还是想发布这个,以防其他人遇到同样的问题或任何人有其他可能的解决方案。


更新:解决方案

我花了很多时间根据提交的答案进行实验,同时也学习了很多关于 iOS 工作原理的知识,所以感谢所有回答的人。

最终,Leon 的回答让我走上了与 a 一起工作的简单解决方案的道路UIPanGestureRecognizer,这与我UISwipeGestureRecognizer根据 Carl 的回答尝试使用 a 的解决方案非常相似,但最终没有产生相同的结果。

我最终进行了子类化UISwitch并添加了一个UIPanGestureRecognizer什么都不做的。这使它的行为完全符合我的意愿:任何时候用户开始滑动开关UIPageViewController都不会平移。

class NoPanSwitch: UISwitch {

    override init(frame: CGRect) {
        super.init(frame: frame)

        let recognizer = UIPanGestureRecognizer(target: self,
                                                action: nil)
        addGestureRecognizer(recognizer)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

标签: iosuipageviewcontrolleruiswitch

解决方案


页面视图控制器具有gestureRecognizers手势识别器控制页面内交互的属性。我会尝试添加一个平移手势识别器UISwitch并将其添加到页面控制器。我期望的效果是页面控制器的平移手势识别器将要求数组中的手势识别器在识别页面平移之前失败,因此当您轻弹开关时不会发生滚动。如果它不能像那样工作,您可能希望将页面控制器交换为带有堆栈或集合视图的滚动视图,其中包含控制器。然后,您将完全控制学校视图panGEstureRecognizer以实现上述行为。


推荐阅读