Aubrey
Aubrey

Reputation: 629

How to use UIViewControllerAnimatedTransitioning in Swift without Storyboards / Unwindng Segues?

I'm having a bit of an issue creating a custom View Controller transition in Swift. I've found this excellent tutorial http://mathewsanders.com/interactive-transitions-in-swift/ but am having trouble figuring out how to create the transition without Storyboards (the app I'm working on does not use interface builder or storyboard).


GIF of desired result:

http://mathewsanders.com/assets/transitions-3/Menu-3.gif


Specifically, the trouble I'm having is in this part where segues are used:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {

let menu = segue.destinationViewController as MenuViewController
menu.transitioningDelegate = self.transitionManager

}

@IBAction func unwindToMainViewController (sender: UIStoryboardSegue){
    // bug? exit segue doesn't dismiss so we do it manually... 
    self.dismissViewControllerAnimated(true, completion: nil)

} 

If you want to forego the segue and Storyboard route, how do you create transitions like this?

My goal is to use a pan gesture to swipe a UICollectionView Detail View down to close (similar to how Facebook photos close it / dismiss the viewcontroller, I know Facebook uses a scrollview for this, but I need to use UICollectionView and a UIViewController that is acting as a detail view for the cell).

Upvotes: 1

Views: 1412

Answers (1)

Hector Matos
Hector Matos

Reputation: 1056

So what you need to do is to put your code in your pan gesture recognizer's event handler. When the gesture recognizer's state changes to UIGestureRecognizerStateBegan, you need to start your transition with UIViewController's presentViewController:animated: method.

class MyViewController: UIViewController {
    var transitionPercentage: CGFloat = 0.0

    func handlePanGestureRecognizer(gestureRecognizer: UIPanGestureRecognizer) {
        let gestureTranslationX: CGFloat = gestureRecognizer.translationInView(view).x
        switch gestureRecognizer.state {
            case .Began: {
                let menuViewController: MenuViewController = MenuViewController()
                menuViewController.transitioningDelegate = self.interactiveTransitionManager;
                presentViewController(menuViewController, animated: true, completion: nil)
            }
            case .Changed: {
                //Here you are going to want to figure out the percentage of your interactive transition. Feed it a threshold of how far you want the finger to move before finishing the transition, and then calculate a percentage for it using our gestureTranslationX variable above.
                transitionPercentage: CGFloat = gestureTranslationX / thresholdValue; //threshold value should be something like self.view.frame.size.width. Our percentage should be no less than 0.0 and no greater than 0.999999. You should probably have logic that prevents this value from violating either one.
                interactiveTransitionManager.updateInteractiveTransition(transitionPercentage) //transitionPercentage is whatever CGFloat variable you use to track the pan state from 0.0 to 1.0
            }
            case .Cancelled, .Ended: {
                //Here you can put logic that uses the transitionPercentage to figure out whether to complete the transition or cancel it.
                if transitionPercentage >= 0.5 {
                    transitionManager.finishInteractiveTransition()
                } else {
                    transitionManager.cancelInteractiveTransition()
                }
            }
        }
    }
}

So I'm assuming you have everything else set up for the interactive transition as outlined in the blog post mentioned in the question but if you have any more questions or need more code don't hesitate to comment in my answer.

Upvotes: 1

Related Questions