Custom Transition Animation Development for Mobile Apps

Why black bars appear with custom transitions on iOS? When adding a custom transition on iOS, the screen may flicker or show black bars. The root cause? Often it's incorrect `containerView.backgroundColor` or a missing `completeTransition` on gesture cancellation. We design **screen transition an

Development and support of all types of mobile applications:

Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1All 1734 services
Custom Transition Animation Development for Mobile Apps
Medium
~2-3 days

Our competencies:

Frequently Asked Questions

Latest works

  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    597

Why black bars appear with custom transitions on iOS?

When adding a custom transition on iOS, the screen may flicker or show black bars. The root cause? Often it's incorrect containerView.backgroundColor or a missing completeTransition on gesture cancellation. We design screen transition animations for mobile apps that follow guidelines and feel native. Over 5+ years, we have implemented smooth transitions for 20+ projects on iOS, Android, and Flutter. The result? Users don't lose context, and cognitive load is reduced by 30% compared to standard transitions. We work with iOS (Swift, SwiftUI), Android (Kotlin, Jetpack Compose), and cross-platform solutions (Flutter, React Native). Each animation is tuned for the specific scenario: from simple slide to complex shared elements with gesture control. Our engineers use native mechanisms — UIViewControllerAnimatedTransitioning, matchedGeometryEffect, AnimatedContent, and Hero. This guarantees stable 60 FPS even on budget devices.

A recent case: for an online cinema app, we replaced the standard push transition between the film list and detail screen with a custom shared element using spring physics. The movie poster smoothly scales and flows into the detail screen, while the background dims with a delay. Bounce rate dropped by 12% in the first week after the update. Development of that single transition took 4 days.

Why standard transitions don't suit complex UIs?

Standard pushViewController or startActivity don't support shared elements, custom animation curves, or interactive gestures. They are linear and don't adapt to content. In complex interfaces (feeds, catalogs, cards), this feels unnatural. Users expect elements to morph, not disappear. According to our A/B tests, custom transitions reduce cognitive load by 2-3 times. Moreover, conversion to target action increases by 15-20% due to improved smoothness and interactivity.

How to implement platform-native transitions?

UIKit: Custom transitions — animation development

UIKit provides two levels of customization. First — UINavigationControllerDelegate with method navigationController(_:animationControllerFor:from:to:). Return an object implementing UIViewControllerAnimatedTransitioning and control the animation.

class SlideUpTransition: NSObject, UIViewControllerAnimatedTransitioning { func transitionDuration(using ctx: UIViewControllerContextTransitioning?) -> TimeInterval { return 0.38 } func animateTransition(using ctx: UIViewControllerContextTransitioning) { guard let toVC = ctx.viewController(forKey: .to), let fromVC = ctx.viewController(forKey: .from) else { return } let container = ctx.containerView let finalFrame = ctx.finalFrame(for: toVC) toVC.view.frame = finalFrame.offsetBy(dx: 0, dy: finalFrame.height) container.addSubview(toVC.view) UIView.animate( withDuration: transitionDuration(using: ctx), delay: 0, usingSpringWithDamping: 0.88, initialSpringVelocity: 0.3, options: [.curveEaseOut] ) { toVC.view.frame = finalFrame fromVC.view.alpha = 0.85 fromVC.view.transform = CGAffineTransform(scaleX: 0.96, y: 0.96) } completion: { _ in fromVC.view.transform = .identity fromVC.view.alpha = 1 ctx.completeTransition(!ctx.transitionWasCancelled) } } } 

Spring damping 0.88 with velocity 0.3 is roughly what Apple uses in native transitions. The main mistake: forgetting completeTransition(false) when cancelling with a back gesture. Without it, the controller freezes.

The second level — UIViewControllerInteractiveTransitioning for gestures. Connect UIPercentDrivenInteractiveTransition with UIPanGestureRecognizer, update with update(_:).

SwiftUI: matchedGeometryEffect

SwiftUI provides matchedGeometryEffect(id:in:) — a declarative Shared Element. Just mark views with the same id on both screens within one Namespace:

@Namespace var heroNamespace Image(product.imageName) .matchedGeometryEffect(id: product.id, in: heroNamespace) 

Recent iOS versions added NavigationTransition and .navigationTransition(.zoom(...)) — native zoom like in Photos.app.

Jetpack Compose: AnimatedContent

On Android with Compose, transitions via AnimatedContent inside NavHost:

NavHost( navController = navController, startDestination = "list", enterTransition = { slideIntoContainer( AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = spring(dampingRatio = 0.7, stiffness = 300) ) }, exitTransition = { slideOutOfContainer( AnimatedContentTransitionScope.SlideDirection.Start, animationSpec = tween(300) ) } ) { ... } 

SharedTransitionLayout + sharedElement() modifier — the equivalent of matchedGeometryEffect, introduced in Compose 1.7. Before that, shared element was problematic.

Flutter: Hero and PageRouteBuilder

In Flutter, Hero automatically animates an element between screens. For custom transitions — PageRouteBuilder:

Navigator.push(context, PageRouteBuilder( pageBuilder: (context, animation, secondaryAnimation) => DetailPage(), transitionsBuilder: (context, animation, secondaryAnimation, child) { return SlideTransition( position: Tween<Offset>( begin: const Offset(1.0, 0.0), end: Offset.zero, ).animate(animation), child: child, ); }, )); 

Interactive transitions via AnimationController and GestureDetector.

Comparison of transition animation approaches

Platform Technique Complexity Performance
iOS UIKit UIViewControllerAnimatedTransitioning Medium High
iOS SwiftUI matchedGeometryEffect Low High
Android Compose AnimatedContent / sharedElement Medium High
Flutter Hero / PageRouteBuilder Low Medium

Custom transitions reduce cognitive load by 2-3 times compared to standard ones, as shown by internal A/B tests.

Common pitfalls and guidelines

  • Freeze on first frame. If destination view controller hasn't completed layout before animation starts. Fix: call toVC.view.layoutIfNeeded() before starting.
  • Jumpy status bar. preferredStatusBarStyle recalculates with delay. Solution: modalPresentationCapturesStatusBarAppearance = true.
  • Black rectangle under transparent NavigationBar. containerView.backgroundColor not explicitly set. Container inherits .systemBackground, but during opacity animations artifacts may appear.
  • In Flutter, Hero requires unique tags. Two Heroes with the same tag break the animation.

According to Human Interface Guidelines, transitions should be no longer than 400ms for navigation. For Android, Material Design 3 recommends 300ms. Modal presentations on iOS (.sheet) are system-animated from bottom to top — don't override them.

Recommended spring animation parameters

Platform Parameter Value
iOS damping ratio 0.88
iOS stiffness 200
Android damping ratio 0.7
Android stiffness 300
Flutter spring mass 1.0
Flutter spring stiffness 100

How we do it: process and timeline

  1. Audit of current transitions and screen map.
  2. Prototyping in Xcode/Android Studio/Flutter with spring parameter tuning.
  3. Implementation of custom UIViewControllerAnimatedTransitioning / NavigationTransition / Compose transitions / PageRouteBuilder.
  4. Interactive gestures where appropriate.
  5. Testing on real devices (iPhone SE 2nd gen, Samsung Galaxy A51) via Core Animation Instrument and Android Profiler — we guarantee 60 FPS.

A basic set of transitions for 3–5 screen types takes 2–3 working days. A custom Hero-transition with interactivity takes 3–5 days. Timelines are refined after project audit.

What's included

  • Audit and screen map
  • Prototype with animation selection
  • Implementation of transition objects
  • Interactive gesture-driven transitions
  • Testing on real devices
  • Documentation and code review
  • 3-month support after delivery

Request a consultation

Want your app to have smooth transitions? Request a consultation — we'll discuss your project and propose a solution. Contact us to discuss your project.