在视图控制器之间平移(不滑动)

Posted

技术标签:

【中文标题】在视图控制器之间平移(不滑动)【英文标题】:Pan (not swipe) between view controllers 【发布时间】:2019-08-15 03:57:13 【问题描述】:

我正在创建一个用户界面类似于 Tinder 的应用。

我的意思是,可以在三个主要视图控制器之间“平移”。用户只需拖动即可移动到三个视图控制器中的任何一个。

我在我的应用中实现了类似的东西,但有一个重要的警告:它使用 swipe 手势识别器,而不是 pan 手势识别器。

最终结果看起来和感觉都很不自然。

这就是我希望我的用户界面的行为方式(忽略 Gecko):

这是它当前使用滑动手势识别器的行为方式:

请注意,使用 Tinder,您可以平移到新的视图控制器,而无需完全提交 segue。并且,如果平移没有将当前视图控制器移位超过最小阈值,它将简单地重新定位。这是我正在寻找的行为。

这是我目前用来模拟滑动手势识别器的一些代码:

//The following logic is applied in a similar way to view controllers 1 and 3 as well.

class ViewController2: UIViewController 

    override func viewDidLoad() 
        super.viewDidLoad()
        addSwipeGestureRecognizers()
    

    func addSwipeGestureRecognizers() 
        let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipeLeft))
        swipeLeft.direction = UISwipeGestureRecognizer.Direction.left
        self.view.addGestureRecognizer(swipeLeft)

        let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipeRight))
        swipeRight.direction = UISwipeGestureRecognizer.Direction.right
        self.view.addGestureRecognizer(swipeRight)
    

    @objc func handleSwipeLeft() 
        let storyboard = UIStoryboard(name: "Main", bundle: .main)
        let viewController1 = storyboard.instantiateViewController(withIdentifier: "ViewController1") as! ViewController1
        let transition:CATransition = CATransition()
        transition.duration = 0.25
        transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
        transition.type = CATransitionType.push
        transition.subtype = CATransitionSubtype.fromLeft
        self.navigationController!.view.layer.add(transition, forKey: kCATransition)
        navigationController!.pushViewController(viewController1, animated: false)
    

    @objc func handleSwipeRight() 
        let storyboard = UIStoryboard(name: "Main", bundle: .main)
        let viewController3 = storyboard.instantiateViewController(withIdentifier: "ViewController3") as! ViewController3
        let transition:CATransition = CATransition()
        transition.duration = 0.25
        transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
        transition.type = CATransitionType.push
        transition.subtype = CATransitionSubtype.fromRight
        self.navigationController!.view.layer.add(transition, forKey: kCATransition)
        navigationController!.pushViewController(viewController3, animated: false)
    

我还使用自定义UIViewControllerAnimatedTransitioning 来使推送的视图控制器将呈现的视图控制器从左侧或右侧推出。这是与呈现视图控制器顶部的默认堆叠相反的。我还隐藏了UINavigationController 的导航栏。

【问题讨论】:

这是一个 UIPageViewController 【参考方案1】:

我不确定 UINavigationController 是否是提供您需要的正确容器控制器。你可能会发现 UIPageViewController 是一个更好的选择,我认为它会提供你正在寻找的开箱即用的自然滑动手势,尽管它是一个相当不透明的类,有一些自己的怪癖。

要走自定义路线(使用 UINavigationController 或更灵活/可自定义的 UIViewController 自定义演示文稿),您可以使用 UIViewControllerAnimatedTransitioning 和其他(众多)相关协议。万一你赶时间,那条路由会花费你相当长的时间来实现,所以现在可能需要一个简单的 UIPageViewController 实现。

【讨论】:

谢谢,我明天试试页面视图控制器。真的没有考虑过。我会回来看看它是怎么回事 是的,就是这样。我花了一些时间熟悉 UIPageViewControllers,但这对我有用。【参考方案2】:

github 上的这个项目可以帮助您实现您的要求 - Here

【讨论】:

以上是关于在视图控制器之间平移(不滑动)的主要内容,如果未能解决你的问题,请参考以下文章

使用平移手势识别器关闭视图控制器

在 Swift 中创建滑动转场

使用不跟随拇指的屏幕边缘平移手势识别器的弹出视图控制器

同一视图中平移和滑动手势之间的冲突?

使用 UIPageViewController 在多个视图控制器之间滑动

(Swift) 需要帮助在视图控制器之间滑动