Transition: basis, animatie van overgangen in mobiele apps

Auteur: IT Sectr Gepubliceerd: 2026-03-02 Leestijd: 11 min

Transition (overgangsanimatie) — een mechanisme voor visuele vervanging van de ene inhoud door de andere: schermen, fragmenten, views of interface statussen. Een correct geïmplementeerde overgang stuurt de aandacht van de gebruiker, legt de relatie tussen elementen uit en maakt navigatie intuïtief. Volgens Material Design Guidelines (2026) tonen apps met doordachte overgangen 22% meer gebruikersbehoud in de tweede sessie. Lees meer over andere animatietypes in de algemene animatiegids.

Belangrijkste punten

  • Transition — animatie van inhoudswisseling tussen schermen, fragmenten of statussen.
  • UIView.transition — de primaire API voor overgangsanimatie in iOS (UIKit).
  • FragmentTransaction.setCustomAnimations — configuratie van overgangsanimatie tussen Fragment in Android.
  • Transition Framework (android.transition) — het declaratieve Android-animatiesysteem voor scene-naar-scene overgangen.
  • UIViewControllerAnimatedTransitioning — het iOS-protocol voor aangepaste overgangen tussen controllers.

Wat is Transition?

Transition — is een animatie die plaatsvindt bij het vervangen van de ene visuele interface-status door een andere. In tegenstelling tot Property Animation (animatie van eigenschappen van één object), beheert Transition een hele reeks wijzigingen: verschijnen/verdwijnen van elementen, verandering van hun positie, grootte en eigenschappen binnen één overgang. Transition lost het probleem van soepele inhoudswisseling op zodat de gebruiker begrijpt wat waar naartoe is verplaatst.

Op mobiele platforms wordt Transition toegepast in drie hoofdscenario's: navigatie tussen schermen (push, pop, modal present), wisselen van fragmenten (Android FragmentTransaction) en statuswijziging binnen een scherm (uitklappen van een kaart, schakelen van tabs). Elk scenario vereist zijn eigen aanpak: navigatie-overgangen — UIViewControllerAnimatedTransitioning in iOS of ActivityOptions in Android, intra-scherm overgangen — Transition Framework of UIView.transition.

Volgens Apple HIG (2026) mag de duur van een standaard overgang niet langer zijn dan 400–500 ms — langere animaties worden als vertraging ervaren. Material Design beveelt 300–350 ms aan voor mobiele overgangen. Voor grote elementen (kaarten, afbeeldingen) kan de tijd oplopen tot 500–600 ms zonder verlies van waargenomen prestaties.

Soorten overgangsanimaties

Soorten overgangen worden onderverdeeld in verschillende categorieën op basis van welke inhoud verandert en hoe. Basistypen: vervaging (cross-fade) — geleidelijk verdwijnen van de ene en verschijnen van de andere; verschuiving (slide) — het ene scherm vertrekt, het andere komt erin; schaling (scale/zoom) — een element wordt groter en opent een gedetailleerd scherm. Gecombineerde overgangen combineren meerdere effecten.

OvergangstypeBeschrijvingiOS APIAndroid API
Cross-fadeVervaging: de ene inhoud verdwijnt, de andere verschijntUIView.transition(with:duration:options:.transitionCrossDissolve)TransitionSet + Fade()
SlideVerschuiving: inhoud vertrekt/komt horizontaal of verticaalCATransition(type: .push, subtype: .fromLeft)Slide() / FragmentTransaction.setCustomAnimations
Scale / ZoomSchaling: element wordt vergroot tot volledig schermUIViewPropertyAnimator met scale-animatieScale() + ActivityOptions.makeScaleUpAnimation
ExplodeExplosie: inhoud valt uit elkaar bij verdwijnenCATransition(type: .reveal)Explode() (API 21+)
Fade-throughVervaging via wit/zwart schermUIView.transition(with: .transitionCrossDissolve, met witte achtergrond)Fade() via ChangeBounds

Material Design regels: gebruik één overgangstype binnen één app voor een uniforme visuele taal. Slide wordt aanbevolen voor navigatie tussen schermen van hetzelfde niveau (master → detail), cross-fade voor inhoudswisseling binnen één scherm (tabs, weergave omschakelen), scale/zoom voor overgang van kaart naar detailscherm (productkaart → beschrijving).

Transition in iOS (Swift)

Op iOS is UIView.transition de eenvoudigste manier om inhoudswisseling binnen één View te animeren. Het ondersteunt cross-dissolve, curl-up, curl-down, flip-from-left, flip-from-right. Voor navigatie-overgangen tussen UIViewController wordt UINavigationControllerDelegate met UIViewControllerAnimatedTransitioning gebruikt — dit geeft volledige controle over de push/pop-animatie.

swift
import UIKit

// UIView.transition: afbeelding wisselen met cross-dissolve
UIView.transition(with: imageView,
    duration: 0.4,
    options: [.transitionCrossDissolve, .curveEaseInOut]
) {
    self.imageView.image = UIImage(named: "new_image")
} completion: { _ in
    print("Transition voltooid")
}

// UIView.transition: twee Views wisselen
UIView.transition(from: firstView, to: secondView,
    duration: 0.5,
    options: [.transitionFlipFromRight, .showHideTransitionViews]
) { _ in
    // firstView verborgen, secondView getoond
}

// CATransition voor laag (zonder Auto Layout)
let transition = CATransition()
transition.type = .push
transition.subtype = .fromRight
transition.duration = 0.35
transition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
view.layer.add(transition, forKey: "pushTransition")

UIViewPropertyAnimator — een modern alternatief voor aangepaste overgangen op iOS 10+. In tegenstelling tot UIView.transition ondersteunt PropertyAnimator pauze, annulering en reverse (omgekeerde animatie), wat belangrijk is voor interactieve overgangen (swipe-to-go-back). Gebruik UIPercentDrivenInteractiveTransition in combinatie met PropertyAnimator voor animatie tussen UIViewController — dit is het standaard patroon voor interactieve navigatie.

Transition in Android (Kotlin)

Op Android is FragmentTransaction met setCustomAnimations de primaire manier om overgangen tussen Fragment te animeren. Parameters: enter (ingangsanimatie van nieuw Fragment), exit (uitgangsanimatie van oud Fragment), popEnter en popExit — voor terug-navigatie. FragmentTransaction ondersteunt resource-animaties (R.anim) en Transition Framework (R.transition).

kotlin
import androidx.fragment.app.FragmentTransaction
import androidx.transition.TransitionInflater

// FragmentTransaction met resource-animaties
supportFragmentManager.beginTransaction()
    .setCustomAnimations(
        R.anim.slide_in_right,  // enter
        R.anim.slide_out_left,  // exit
        R.anim.slide_in_left,   // popEnter
        R.anim.slide_out_right  // popExit
    )
    .replace(R.id.container, DetailFragment())
    .addToBackStack(null)
    .commit()

// FragmentTransaction met Transition Framework
val detailFragment = DetailFragment()
detailFragment.enterTransition = TransitionInflater.from(this)
    .inflateTransition(R.transition.slide_right)
detailFragment.exitTransition = TransitionInflater.from(this)
    .inflateTransition(R.transition.fade_out)

supportFragmentManager.beginTransaction()
    .replace(R.id.container, detailFragment)
    .addToBackStack(null)
    .commit()

// ActivityOptions: animatie bij starten van Activity
val options = ActivityOptions.makeScaleUpAnimation(
    view, 0, 0, view.width, view.height
).toBundle()
startActivity(intent, options)

Beste praktijken Android: Slide() — voor het vervangen van Fragment in navigatie (enter = Slide(Gravity.END), exit = Slide(Gravity.START)). Fade() — voor tonen/verbergen van overlays en dialoogvensters. Explode() — voor geaccentueerde overgangen (verwijderen van een element uit een lijst). Gebruik R.anim als fallback voor oudere apparaten (API < 21). Transition Framework ondersteunt geen SurfaceView, TextureView, GLSurfaceView — gebruik voor video en camera alleen animaties via R.anim.

Aangepaste UIViewController-overgangen in iOS

UIViewControllerAnimatedTransitioning — het iOS-protocol voor het maken van volledig aangepaste overgangsanimaties tussen controllers. Het geeft toegang tot de container View (transitionContext.containerView), de bron- en doel-View. In combinatie met UIPercentDrivenInteractiveTransition maakt deze aanpak het mogelijk interactieve overgangen te creëren met vegen.

swift
import UIKit

"> Aangepaste overgangsanimator
class ScaleTransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning {
    let isPresenting: Bool

    init(presenting: Bool) { self.isPresenting = presenting }

    func transitionDuration(using ctx: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.4
    }

    func animateTransition(using ctx: UIViewControllerContextTransitioning) {
        guard let toView = ctx.view(forKey: .to),
              let fromView = ctx.view(forKey: .from)
        else { return }

        let container = ctx.containerView
        let initialScale: CGAffineTransform = CGAffineTransform(scaleX: 0.8, y: 0.8)
        let finalFrame = ctx.finalFrame(for: toView)

        if isPresenting {
            toView.transform = initialScale
            toView.alpha = 0
            toView.frame = finalFrame
            container.addSubview(toView)
        }

        UIView.animate(withDuration: transitionDuration(using: ctx),
                       delay: 0,
                       usingSpringWithDamping: 0.7,
                       initialSpringVelocity: 0.3) {
            if self.isPresenting {
                toView.transform = .identity
                toView.alpha = 1
                fromView.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
                fromView.alpha = 0
            } else {
                fromView.transform = initialScale
                fromView.alpha = 0
            }
        } completion: { _ in
            fromView.transform = .identity
            ctx.completeTransition(!ctx.transitionWasCancelled)
        }
    }
}

// Toepassing in UINavigationControllerDelegate
extension MainViewController: UINavigationControllerDelegate {
    func navigationController(
        _ nc: UINavigationController,
        animationControllerFor operation: UINavigationController.Operation,
        from: UIViewController, to: UIViewController
    ) -> UIViewControllerAnimatedTransitioning? {
        return ScaleTransitionAnimator(presenting: operation == .push)
    }
}

Interactieve overgangen: voeg een UIPanGestureRecognizer toe aan het bron-scherm. Bij activering van het gebaar, maak een UIPercentDrivenInteractiveTransition aan en roep update(CGFloat(percent)) aan. Voor annulering bij niet bereiken van de drempel (meestal 30%) roep cancel() aan. Dit patroon wordt standaard gebruikt in UINavigationController bij het pop-gebaar en in UIScrollView met pagingEnabled. Implementeer UIViewControllerInteractiveTransitioning voor aangepaste gebaren.

Transition Framework in Android: scene naar scene

Transition Framework (android.transition) — is een declaratief animatiesysteem dat automatisch wijzigingen tussen twee scenes (Scene) animeert. Een scene is een set Views met een bepaalde status. Bij overgang van Scene A naar Scene B analyseert Transition Framework het verschil en animeert: positieverandering (ChangeBounds), grootteverandering (ChangeClipBounds, ChangeTransform), verschijnen (Fade) en verdwijnen (Fade).

kotlin
import android.transition.Scene
import android.transition.TransitionManager
import android.transition.TransitionSet
import android.transition.AutoTransition
import android.transition.ChangeBounds
import android.transition.Fade

// TransitionSet: combinatie ChangeBounds + Fade
val transition = TransitionSet().apply {
    ordering = TransitionSet.ORDERING_TOGETHER
    addTransition(ChangeBounds())
    addTransition(Fade(Fade.IN))
    duration = 400L
    interpolator = FastOutSlowInInterpolator()
}

// Overgang tussen scenes in ViewGroup
val sceneRoot = findViewById<ViewGroup>(R.id.scene_root)
val scene1 = Scene.getSceneForLayout(sceneRoot, R.layout.scene_initial)
val scene2 = Scene.getSceneForLayout(sceneRoot, R.layout.scene_expanded)

"> AutoTransition zonder handmatige configuratie
TransitionManager.go(scene2, AutoTransition().apply {
    duration = 350L
})

// TransitionManager.beginDelayedTransition — zonder scenes
TransitionManager.beginDelayedTransition(sceneRoot, ChangeBounds())
itemView.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
itemView.requestLayout() "> Wijziging van de layout wordt automatisch geanimeerd

ChangeBounds — de meest gebruikte overgang in Android, animeert verandering van positie en grootte van View. ChangeTransform animeert rotation en scale. ChangeImageTransform — voor animatie van ImageView (centerCrop → fitCenter). Gebruik voor complexe overgangen met wijziging van de hiërarchiestructuur TransitionSet met ordering = ORDERING_SEQUENTIAL (animaties worden sequentieel uitgevoerd, niet parallel). Volgens de documentatie van Android Developers (2026) ondersteunt Transition Framework alle standaard Views, maar geen oppervlakte-animatie (SurfaceView, TextureView, VideoView).

Veelgestelde vragen

Wat is het verschil tussen Transition en Animation?

Animation — animatie van eigenschappen van één object (alpha, translation, scale). Transition — animatie van verandering van een set objecten of statussen (fragment → fragment, scene → scene). Transition beheert meerdere wijzigingen tegelijk: verschijnen, verdwijnen, verplaatsen, grootteverandering — en animeert automatisch het verschil tussen twee toestanden. Animation vereist handmatig beheer van elke eigenschap.

Hoe maak je een soepele overgang tussen Android-fragmenten?

Gebruik FragmentTransaction.setCustomAnimations met Transition Framework: fragment1.exitTransition = Fade(Fade.OUT), fragment2.enterTransition = Slide(Gravity.END). Voor volgorde: setReorderingAllowed(true) — fragmenten worden herordend voor een soepele parallelle overgang. Voor eenvoudige gevallen volstaan slide_in_right / slide_out_left uit R.anim. Specificeer popEnter en popExit voor terug-navigatie.

Transition Framework animeert hoogteverandering van View niet — wat te doen?

Transition Framework animeert alleen eigenschappen die geen herberekening van de layout veroorzaken. Gebruik ChangeBounds voor hoogte-animatie — het animeert automatisch verandering van View-grenzen tussen twee layout-toestanden. Roep TransitionManager.beginDelayedTransition(viewGroup, ChangeBounds()) aan vóór het wijzigen van LayoutParams. Als de hoogte verandert via WRAP_CONTENT, zorg dan dat layout_height voor en na verschilt — ChangeBounds werkt niet als beide toestanden match_parent zijn.

Hoe maak je een aangepaste overgang in SwiftUI?

Gebruik de .transition() modifier met AnyTransition: .transition(.move(edge: .trailing).combined(with: .opacity)). Voor aangepaste overgangen implementeer AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)). Gebruik .navigationTransition(.slide) in NavigationStack op iOS 18+. SwiftUI ondersteunt UIViewControllerAnimatedTransitioning niet — alleen declaratieve overgangen via AnyTransition.

Hoe meet je de prestaties van Transition?

Gebruik Profile GPU Rendering (Android) of Core Animation Instrument (iOS). Voeg voor Android Transition-profilering toe via adb shell setprop debug.transition.profiling 1 — in de logs verschijnen de duur van elke overgangsfase. Schakel op iOS Slow Animations in de simulator in. Doelstellingen: duur < 400 ms, FPS >= 55, frame drops — niet meer dan 2 per overgang. Gebruik voor complexe scenes met 15+ gelijktijdig geanimeerde Views ChangeBounds met duration 300 ms.

Samenvatting

  • Transition — animatie van inhoudswisseling tussen schermen, fragmenten of interface-statussen.
  • UIView.transition (iOS) — basis-API voor cross-dissolve, flip, curl overgangen binnen een View.
  • UIViewControllerAnimatedTransitioning (iOS) — protocol voor aangepaste overgangen tussen controllers.
  • FragmentTransaction.setCustomAnimations (Android) — overgangsanimatie tussen Fragment.
  • Transition Framework (android.transition) — declaratief scenesysteem: ChangeBounds, Fade, Slide, Explode.
  • Aanbevolen duur: 300–400 ms voor mobiel, tot 600 ms voor grote elementen.
  • Eén overgangstype per app voor uniforme visuele taal (Material Design).

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook