iOS Functions

 

Creating Custom Transition Animations in iOS: UIViewControllerAnimatedTransitioning

Transition animations play a crucial role in enhancing the user experience of iOS applications. They can make your app feel more polished and visually appealing. While iOS provides some built-in transition animations, there are times when you need to create custom animations to achieve the desired effect.

Creating Custom Transition Animations in iOS: UIViewControllerAnimatedTransitioning

In this blog post, we’ll dive deep into creating custom transition animations in iOS using UIViewControllerAnimatedTransitioning. We’ll explore how to implement custom transitions step by step, allowing you to take complete control over how your view controllers transition between each other.

1. Understanding UIViewControllerAnimatedTransitioning

UIViewControllerAnimatedTransitioning is a protocol in iOS that allows you to define custom transition animations when presenting or dismissing view controllers. By conforming to this protocol, you can implement your own animation logic and provide a seamless and unique user experience.

1.1. Implementing UIViewControllerAnimatedTransitioning

To get started, you need to create a custom class that conforms to the UIViewControllerAnimatedTransitioning protocol. This class will be responsible for defining the animation logic for your transitions.

Here’s a simple example of what your custom transition class might look like:

swift
import UIKit

class CustomTransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning {
    
    // Define the duration of the animation
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.5
    }
    
    // Define the transition animation
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        // Implement your custom animation logic here
    }
}

In this example, we’ve created a CustomTransitionAnimator class that conforms to UIViewControllerAnimatedTransitioning. It defines two methods:

  • transitionDuration(using:): This method specifies the duration of the transition animation in seconds. You can return any positive value that suits your animation.
  • animateTransition(using:): This is where you implement the actual animation logic. This method receives a transitionContext object, which contains information about the transition and the view controllers involved.

1.2. Configuring the Transitioning Delegate

To use your custom transition animator, you need to set it as the transitioning delegate for the view controller that you want to present or dismiss with a custom animation.

swift
class ViewController: UIViewController {
    
    let customTransitionAnimator = CustomTransitionAnimator()
    
    // ...

    func presentNextViewController() {
        let nextViewController = NextViewController()
        
        // Set the transitioning delegate to the custom animator
        nextViewController.transitioningDelegate = customTransitionAnimator
        
        // Present the view controller with a custom animation
        present(nextViewController, animated: true, completion: nil)
    }
}

In the example above, we create an instance of CustomTransitionAnimator and set it as the transitioning delegate for the NextViewController. When we present NextViewController, the custom animation defined in CustomTransitionAnimator will be used.

2. Creating a Custom Transition Animation

Now that we have the basic setup in place, let’s dive deeper into creating a custom transition animation. We’ll use a simple example of sliding a view controller from the bottom of the screen.

2.1. Implementing the Animation Logic

In the animateTransition(using:) method of your custom transition animator, you’ll define the animation logic. For our sliding animation, we’ll translate the view controller’s view from below the screen to its final position.

Here’s how you can implement the animation logic:

swift
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    // Get the from and to view controllers and their views
    let fromViewController = transitionContext.viewController(forKey: .from)!
    let toViewController = transitionContext.viewController(forKey: .to)!
    let containerView = transitionContext.containerView
    
    // Set the initial position of the to view
    toViewController.view.frame = CGRect(
        x: 0,
        y: containerView.frame.height,
        width: containerView.frame.width,
        height: containerView.frame.height
    )
    
    // Add the to view to the container view
    containerView.addSubview(toViewController.view)
    
    // Perform the animation
    UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
        toViewController.view.frame = CGRect(
            x: 0,
            y: 0,
            width: containerView.frame.width,
            height: containerView.frame.height
        )
    }) { _ in
        // Complete the transition
        transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
    }
}

In this code snippet:

  • We obtain references to the from and to view controllers and their views using the transitionContext.
  • We set the initial position of the to view below the screen.
  • We add the to view to the container view.
  • We use UIView.animate to animate the to view’s frame from its initial position to its final position.
  • Finally, we call transitionContext.completeTransition to complete the transition.

2.2. Triggering the Custom Transition

To trigger the custom transition, you simply present or dismiss the view controller as you normally would:

swift
func presentNextViewController() {
    let nextViewController = NextViewController()
    
    // Set the transitioning delegate to the custom animator
    nextViewController.transitioningDelegate = customTransitionAnimator
    
    // Present the view controller with a custom animation
    present(nextViewController, animated: true, completion: nil)
}

The custom transition will be automatically triggered when you present NextViewController with the defined animation logic.

3. Custom Transition Types

The example above demonstrated a simple sliding transition animation. However, you can create a wide variety of custom transitions by altering the animation logic in your CustomTransitionAnimator class.

3.1. Crossfade Transition

Let’s create a crossfade transition where the new view controller gradually appears while the previous one fades out.

swift
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    // Get the from and to view controllers and their views
    let fromViewController = transitionContext.viewController(forKey: .from)!
    let toViewController = transitionContext.viewController(forKey: .to)!
    let containerView = transitionContext.containerView
    
    // Add the to view to the container view
    containerView.addSubview(toViewController.view)
    
    // Set the initial alpha of the to view to 0
    toViewController.view.alpha = 0
    
    // Perform the animation
    UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
        toViewController.view.alpha = 1
    }) { _ in
        // Remove the from view and complete the transition
        fromViewController.view.removeFromSuperview()
        transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
    }
}

In this code snippet, we set the initial alpha of the to view to 0 and gradually fade it in while fading out the from view.

3.2. Customizing Your Transitions

The possibilities are nearly endless when it comes to custom transitions. You can experiment with different animations, rotations, scaling, and more to create unique and engaging transitions for your iOS app.

4. Handling Interactive Transitions

In addition to creating custom non-interactive transitions, you can also implement interactive transitions. Interactive transitions allow users to interact with the transition animation, such as dragging or tapping to control the animation’s progress.

4.1. Implementing Interactive Transitions

To implement an interactive transition, you’ll need to create a custom interaction controller that conforms to the UIViewControllerInteractiveTransitioning protocol. This interaction controller will handle user interactions and update the transition’s progress accordingly.

Here’s a simplified example of an interactive transition where the user can swipe up to dismiss the current view controller:

swift
import UIKit

class SwipeUpInteractionController: NSObject, UIViewControllerInteractiveTransitioning {
    
    private var transitionContext: UIViewControllerContextTransitioning?
    private var isInteractiveTransitioning = false
    private var shouldFinishTransition = false
    
    // Add gesture recognizer to your view controller
    func addSwipeGestureRecognizer(to view: UIView) {
        let swipeGesture = UIPanGestureRecognizer(target: self, action: #selector(handleSwipe(_:)))
        view.addGestureRecognizer(swipeGesture)
    }
    
    @objc func handleSwipe(_ gestureRecognizer: UIPanGestureRecognizer) {
        guard let transitionContext = transitionContext else { return }
        
        let translation = gestureRecognizer.translation(in: gestureRecognizer.view)
        let verticalMovement = translation.y / transitionContext.containerView.bounds.height
        
        switch gestureRecognizer.state {
        case .began:
            isInteractiveTransitioning = true
            transitionContext.viewController(forKey: .to)?.dismiss(animated: true, completion: nil)
        case .changed:
            shouldFinishTransition = verticalMovement > 0.5
            update(shouldFinishTransition ? 1.0 : verticalMovement)
        case .cancelled, .ended:
            isInteractiveTransitioning = false
            if shouldFinishTransition {
                finish()
            } else {
                cancel()
            }
        default:
            break
        }
    }
    
    func startInteractiveTransition(_ transitionContext: UIViewControllerContextTransitioning) {
        self.transitionContext = transitionContext
    }
    
    func update(_ percentComplete: CGFloat) {
        transitionContext?.updateInteractiveTransition(percentComplete)
    }
    
    func cancel() {
        transitionContext?.cancelInteractiveTransition()
    }
    
    func finish() {
        transitionContext?.finishInteractiveTransition()
    }
}

In this example, we create a SwipeUpInteractionController that handles swipe gestures to dismiss the view controller interactively. We use a UIPanGestureRecognizer to track the user’s swipe gesture and update the transition’s progress accordingly.

4.2. Integrating the Interaction Controller

To use the interaction controller, you’ll need to integrate it with your custom transition. Here’s how you can set up an interactive transition:

swift
class ViewController: UIViewController {
    
    let customTransitionAnimator = CustomTransitionAnimator()
    let swipeInteractionController = SwipeUpInteractionController()
    
    // ...
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Set up the swipe gesture recognizer
        swipeInteractionController.addSwipeGestureRecognizer(to: view)
    }
    
    func presentNextViewController() {
        let nextViewController = NextViewController()
        
        // Set the transitioning delegate to the custom animator
        nextViewController.transitioningDelegate = customTransitionAnimator
        
        // Set up the interaction controller
        customTransitionAnimator.interactionController = swipeInteractionController
        
        // Present the view controller with a custom animation
        present(nextViewController, animated: true, completion: nil)
    }
}

In this code, we create an instance of SwipeUpInteractionController and add a swipe gesture recognizer to the view controller’s view. When we present NextViewController, we set the interaction controller as part of the custom transition animator. This allows the user to interactively dismiss the view controller with a swipe-up gesture.

Conclusion

Creating custom transition animations in iOS using UIViewControllerAnimatedTransitioning opens up a world of possibilities to enhance your app’s user experience. You can create stunning and engaging transitions that set your app apart from the competition.

Remember that custom transitions require careful consideration of your app’s design and user flow. When used appropriately, they can elevate your app’s visual appeal and provide a seamless and enjoyable user experience.

So go ahead, experiment with custom transitions, and take your iOS app to the next level with captivating animations that leave a lasting impression on your users. Happy coding!

In this blog post, we’ve explored the fundamentals of creating custom transition animations in iOS using UIViewControllerAnimatedTransitioning. We’ve covered how to implement custom transitions, create various types of animations, and even implement interactive transitions for a more engaging user experience. By mastering custom transitions, you can make your iOS app stand out with stunning and unique animations.

Previously at
Flag Argentina
Brazil
time icon
GMT-3
Skilled iOS Engineer with extensive experience developing cutting-edge mobile solutions. Over 7 years in iOS development.