ios - 当在其中一个页面中包含的 UISwitch 上开始触摸时禁用 UIPageViewController 滚动

标签 ios uipageviewcontroller uiswitch

我有一个 UIPageViewController其中一页是设置屏幕。在那个屏幕上,有一个 UISwitch打开或关闭设置。

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

试图滑动 UISwitch当它在 UIViewController 上时可能会导致问题这是 UIPageViewController 的一部分,因为滑动开关可以开始滑动UIPageViewController就好像用户想要更改页面一样。

这种行为让人感觉非常 splinter 和不一致。似乎如果用户触摸开关,但在滑动前短暂犹豫,则触摸由 UISwitch 注册。它可以按用户期望的那样工作。但是,如果用户触摸 UISwitch并立即开始滑动,UIPageViewController取而代之的是接​​触。 UISwitch之间似乎有一条很细的线(犹豫阈值)接触与否。

你会如何解决这个问题?

这是一个从简单的点击开始切换 UISwitch 的示例。 ,然后展示了尝试滑动 UISwitch 的一些不同方法。导致结果不一致:

inconsistent-uiswitch-behavior

可能的解决方案和问题

我考虑过解决这个问题的一种方法是检测设置 UIViewController 上任意位置的触摸。 ,并且如果触摸开始于 UISwitch 的框架中的某处,防止UIPageViewController从滑动。

我担心的是简单地禁用 UIPageViewController 的滑动不能保证将触摸传递给 UISwitch .这意味着用户可能会尝试滑动 UISwitchUIPageViewController不会滑动,但UISwitch也不会对触摸使用react,使其看起来仍然 splinter 和不一致。

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

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

    print("touchesBegan")

    super.touchesBegan(touches,
                       with: event)
}

我已经尝试在 UIPageViewController 上以这种方式检测触摸和 UIViewController的特定设置页面,但都没有被调用。我也试过设置 view.isUserInteractionEnabled = true关于 View ,以及 true 的不同组合或 false关于不同 UIViewController s,但似乎仍然无法检测到触摸。

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

更新:解决方案

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

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

我最终继承了 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")
    }
}

最佳答案

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

关于ios - 当在其中一个页面中包含的 UISwitch 上开始触摸时禁用 UIPageViewController 滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53805573/

相关文章:

iphone - 可以在 iPhone 的状态栏中添加另一个时钟吗?

IOS UIPageViewController - 仅滑动屏幕的一部分

ios - UIPageViewController如何访问不可见页面

ios - 滚动 UITableView 时,UISwitch 多次添加到 UITableViewCell - Swift

ios - 如何动画进度 View ?

objective-c - iOS - 从文件初始化数组

ios - 由于未捕获的异常 'NSRangeException' 而终止应用程序,原因 : '*** -[__NSArray0 objectAtIndex:]

iphone - UIPageviewController PDF

ios - 没有获取用于在 UITableViewCell 中点击 UISwitch 的 indexPath

ios - UISwitch 在 Xcode 9.3 的模拟器中损坏?