Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Segue animation Horizontal without UINavigationController?

I am using a UISplitViewController, with a MasterViewController and DetailViewController, without UINavigationControllers.

Currenly the segue animation for master->detail, triggered by

performSegueWithIdentifier("showDetail", sender: self)

consists in the DetailViewController showing up from the bottom upwards.

How can I make that animation showing left-wards?

like image 775
Daniele B Avatar asked Nov 20 '15 13:11

Daniele B


3 Answers

Embed your view controllers in UINavigationControllers.

Per the SplitViewController template: enter image description here

On smaller devices it's going to have to use the Master's navigationController.

Furthermore this question has been answered here and here and here

More from the View Controller Programming Guide:

There are two ways to display a view controller onscreen: embed it in a container view controller or present it. Container view controllers provide an app’s primary navigation….

In storyboards it's not that difficult to embed something in a navigation controller. Click on the view controller you want to embed, then Editor->embed in->navigation controller.

like image 91
beyowulf Avatar answered Oct 31 '22 07:10

beyowulf


I've recently needed to have more control of how the segues are being performed, so I made my custom segue classes which all perform the transition in different directions. Here's one of the implementations:

Swift 2.x

override func perform() {

    //credits to http://www.appcoda.com/custom-segue-animations/

    let firstClassView = self.sourceViewController.view
    let secondClassView = self.destinationViewController.view

    let screenWidth = UIScreen.mainScreen().bounds.size.width
    let screenHeight = UIScreen.mainScreen().bounds.size.height

    secondClassView.frame = CGRectMake(screenWidth, 0, screenWidth, screenHeight)

    if let window = UIApplication.sharedApplication().keyWindow {

        window.insertSubview(secondClassView, aboveSubview: firstClassView)

        UIView.animateWithDuration(0.4, animations: { () -> Void in

            firstClassView.frame = CGRectOffset(firstClassView.frame, -screenWidth, 0)
            secondClassView.frame = CGRectOffset(secondClassView.frame, -screenWidth, 0)

            }) {(Finished) -> Void in

                self.sourceViewController.navigationController?.pushViewController(self.destinationViewController, animated: false)

        }

    }

}

This one will have a "right to left" transition. You can modify this function for your needs by simply changing the initial and ending positions of the source and destination view controller.

Also don't forget that you need to mark your segue as "custom segue", and to assign the new class to it.

UPDATE: Added Swift 3 version

Swift 3

override func perform() {

    //credits to http://www.appcoda.com/custom-segue-animations/

    let firstClassView = self.source.view
    let secondClassView = self.destination.view

    let screenWidth = UIScreen.main.bounds.size.width
    let screenHeight = UIScreen.main.bounds.size.height

    secondClassView?.frame = CGRect(x: screenWidth, y: 0, width: screenWidth, height: screenHeight)

    if let window = UIApplication.shared.keyWindow {

        window.insertSubview(secondClassView!, aboveSubview: firstClassView!)

        UIView.animate(withDuration: 0.4, animations: { () -> Void in

            firstClassView?.frame = (firstClassView?.frame.offsetBy(dx: -screenWidth, dy: 0))!
            secondClassView?.frame = (secondClassView?.frame.offsetBy(dx: -screenWidth, dy: 0))!

        }, completion: {(Finished) -> Void in

            self.source.navigationController?.pushViewController(self.destination, animated: false)

        }) 

    }

}
like image 38
Armin Avatar answered Oct 31 '22 08:10

Armin


--Swift 3.0--

Armin's solution adapted for swift 3. New -> File -> Cocoa Touch Class -> Class: ... (Subclass: UIStoryboardSegue).

import UIKit

class SlideHorSegue: UIStoryboardSegue {
    override func perform() {

        //credits to http://www.appcoda.com/custom-segue-animations/

        let firstClassView = self.source.view
        let secondClassView = self.destination.view

        let screenWidth = UIScreen.main.bounds.size.width
        let screenHeight = UIScreen.main.bounds.size.height

        secondClassView?.frame = CGRect(x: screenWidth, y: 0, width: screenWidth, height: screenHeight)

        if let window = UIApplication.shared.keyWindow {

            window.insertSubview(secondClassView!, aboveSubview: firstClassView!)

            UIView.animate(withDuration: 0.4, animations: { () -> Void in

                firstClassView?.frame = (firstClassView?.frame)!.offsetBy(dx: -screenWidth, dy: 0)
                secondClassView?.frame = (secondClassView?.frame)!.offsetBy(dx: -screenWidth, dy: 0)

            }) {(Finished) -> Void in

                self.source.navigationController?.pushViewController(self.destination, animated: false)

            }

        }

    }

}

In storyboard: mark your segue as "custom segue", and to assign the new class to it.

Note: If you have a UIScrollView in your detailesVC, this won't work.

like image 39
Mr_Vlasov Avatar answered Oct 31 '22 08:10

Mr_Vlasov