Pan (not swipe) between view controllers

旧时模样 提交于 2020-02-07 03:38:52

问题


I am creating an app that has a user interface similar to Tinder.

By this, I mean that there are three primary view controllers that can be "panned" between. The user can simply drag to move to any of the three view controllers.

I have implemented something similar in my app with one important caveat: it utilizes swipe gesture recognizers and not pan gesture recognizers.

The end-result looks and feels very unnatural.

This is how I'd like my user interface to behave (ignore the Gecko):

This is how it currently behaves with a swipe gesture recognizer:

Notice how with Tinder, you can pan to a new view controller without having completely committed the segue. And, if the pan hasn't displaced the current view controller beyond a minimum threshold, it will simply snap back into place. This is the behavior I am looking for.

Here is some code that I am currently using to mimic with a swipe gesture recognizer:

//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)
    }
}

I am also utilizing a custom UIViewControllerAnimatedTransitioning to make the pushed view controllers push the presenting view controller out from the left or right. This is done as opposed to the default stacking on top of the presenting view controller. I also have my UINavigationController's navigation bar hidden.


回答1:


I'm not sure UINavigationController is the correct container controller to provide what you need. You might find that UIPageViewController is a better choice, I think it will provide the natural swipe gesture you are looking for out of the box, although it's quite an opaque class with some quirks of its own.

To go the custom route (either with UINavigationController or the more flexible/customisable UIViewController custom presentation) you are on the right track with UIViewControllerAnimatedTransitioning and the other (numerous) associated protocols. In case you are in a hurry, that route will take you quite a long time to implement, so maybe a simple UIPageViewController implementation will have to do for the moment.




回答2:


This project on github may help you in achieving your requirement - Here



来源:https://stackoverflow.com/questions/57504675/pan-not-swipe-between-view-controllers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!