仅在 uiPageViewController 中禁用临时向前滑动

Posted

技术标签:

【中文标题】仅在 uiPageViewController 中禁用临时向前滑动【英文标题】:Disable temporarily forward swipe only in uiPageViewController 【发布时间】:2016-10-04 17:33:46 【问题描述】:

我正在使用 uiPageViewController(底部的图像)编写一系列设置/设置屏幕。用户配置东西,然后滑动到下一个屏幕,依此类推。但我想锁定/禁用/阻止向前滑动,直到用户在当前屏幕中完成设置。

我试过了:

1) uiPageViewController.view.userInteractionEnabled = false。它会阻止屏幕上的所有内容,包括向后滑动。我只想阻止前锋。

2)

func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? 
    if !forwardSwipeEnabled 
        return nil
    
    var index  = contentViewControllers.indexOf(viewController)
    index += 1
    return contentViewControllers[index]

forwardSwipeEnabled 设置为false 时到return nil,并且它可以工作,但是即使在我更改forwardSwipeEnabled = true 之后,向前滑动仍然被阻止,因为当场景出现在屏幕上时UIPageViewController 已经调用了这个函数。

如果我再次来回前进,则再次调用该函数并且它可以工作。

-- 编辑 -----

使用当前视图控制器调用 pageViewController!.setViewControllers(viewControllers, direction: .Forward, animated: false, completion: nil) 不会刷新或再次调用该函数。

3) 仅在用户完成后追加下一个屏幕(UIViewcontroller),但会出现与 2) 相同的问题。

-- 编辑 -----

4) 我可以使用view.subviews.first?.gestureRecognizers 获得手势识别器,但是将它们设置为gestureRecognize.enabled = false 会阻止正向和反向。每个人都没有不同的手势识别器可以选择性地阻止。

5) 在方向为正向或让它运行时拦截手势并吃掉它,反向时底部代码不起作用,因为用户可以开始向后滑动,触发函数返回并向前完成。

override func viewDidLoad() 
    super.viewDidLoad()
    for view: UIView in pageViewController!.view.subviews 
        if (view is UIScrollView) 
            let scrollView = (view as! UIScrollView)
            self.scrollViewPanGestureRecognzier = UIPanGestureRecognizer()
            self.scrollViewPanGestureRecognzier.delegate = self
            scrollView.addGestureRecognizer(scrollViewPanGestureRecognzier)
        
    


    func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool 
    if gestureRecognizer == scrollViewPanGestureRecognzier 
        guard let panGestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer else  return false 
        let velocity = panGestureRecognizer.velocityInView(view)
        let translation = panGestureRecognizer.translationInView(view)
        if translation.x < 0 
            return true
        
        if velocity.x < 0 
            return true
        
        return false
    
    return false


示例屏幕:

【问题讨论】:

"但我想锁定/禁用/阻止向前滑动,直到用户在当前屏幕完成设置。"你的基本策略是正确的。 viewControllerAfterViewController 委托方法应该简单地返回 nil 以防止向前滑动。 @matt ,如 2) 中所述,在我更改告诉它阻塞的环境变量后,它会阻塞,但不会解除阻塞。而且我无法刷新框架,因此它再次调用该函数以解除阻塞。它仍然卡住,除非用户返回上一页并再次转发到被锁定的页面。 对,这一定是因为运行时对自己说,嘿,我已经知道这个视图控制器的答案,所以我不需要再调用这个方法了。但这就是@kocakmstf 的建议有意义的原因。您需要自己替换另一个视图控制器,提供同一视图控制器的新实例,以便再次调用委托方法。 有道理,但不起作用。我已经做到了。该函数不再被调用。 :-( 【参考方案1】:

作为建议,您可以在完成工作后使用setViewControllers:direction:animated:completion 重新加载数据源。这应该可以修复您的下一页。 它的 obj-c 代码。它应该在 swift 中具有相同的代码。

【讨论】:

不幸的是不起作用。不再调用“viewControllerAfterViewController”函数。 :-(【参考方案2】:

这些年你找到解决方案了吗? 我只找到了一个:如果禁止前进,请立即返回:

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) 
    let pageContentViewController = pageViewController.viewControllers![0]
    let currentPage = orderedViewControllers!.index(of: pageContentViewController)!
    if !nextButton.isEnabled && currentPage > pageControl.currentPage 
        DispatchQueue.main.asyncAfter(deadline: .now()+0.05, execute:  
            self.setViewControllers([self.orderedViewControllers![self.pageControl.currentPage]], direction: .reverse, animated: false, completion: nil)
        )
    

【讨论】:

以上是关于仅在 uiPageViewController 中禁用临时向前滑动的主要内容,如果未能解决你的问题,请参考以下文章

带有 Aspect Fill 图像模式的奇怪 UIPageViewController 滑动行为

如何仅在第一次启动 IOS Swift 时显示页面控制器

uipageviewcontroller 中的 Swift uipageviewcontroller

UIPageViewController 背景在 Objective C iOS 中从不透明

在故事板中使用 UIPageViewController

在 UIPageViewController 中获取用户滑动方向