Transition: основе, анимација прелаза у мобилним апликацијама

Аутор: IT Sectr Објављено: 2026-03-02 Време читања: 11 мин

Transition (анимација прелаза) — механизам визуелне смене једног садржаја другим: екрана, фрагмената, вјуова или стања интерфејса. Правилно имплементиран прелаз усмерава пажњу корисника, објашњава међусобну везу између елемената и чини навигацију интуитивном. Према Material Design Guidelines (2026), апликације са промишљеним прелазима показују 22% веће задржавање корисника у другој сесији. Више о другим врстама анимације прочитајте у општем водичу за анимацију.

Главно

  • Transition — анимација смене садржаја између екрана, фрагмената или стања.
  • UIView.transition — основни API за анимацију прелаза у iOS (UIKit).
  • FragmentTransaction.setCustomAnimations — подешавање анимације прелаза између Fragment у Android.
  • Transition Framework (android.transition) — декларативни систем анимације Android за прелаз сцене у сцену.
  • UIViewControllerAnimatedTransitioning — протокол iOS за прилагођене прелазе између контролера.

Шта је Transition?

Transition — је анимација која се дешава при замени једног визуелног стања интерфејса другим. За разлику од Property Animation (анимације својства једног објекта), Transition управља целим скупом промена: појављивањем/нестајањем елемената, променом њихове позиције, величине и својстава у оквиру једног прелаза. Transition решава проблем глатке смене садржаја тако да корисник разуме шта се куда померило.

На мобилним платформама Transition се примењује у три главна сценарија: навигација између екрана (push, pop, modal present), смена фрагмената (Android FragmentTransaction) и промена стања унутар екрана (развијање картице, пребацивање картица). Сваки сценариј захтева свој приступ: навигациони прелази — UIViewControllerAnimatedTransitioning у iOS или ActivityOptions у Android, унутарекрански прелази — Transition Framework или UIView.transition.

Према Apple HIG (2026), трајање стандардног прелаза не сме да пређе 400–500 ms — дуже анимације се доживљавају као кашњење. Material Design препоручује 300–350 ms за мобилне прелазе. За велике елементе (картице, слике) време може да се повећа на 500–600 ms без губитка перципираних перформанси.

Типови анимација прелаза

Типови прелаза деле се на неколико категорија у зависности од тога који се садржај мења и како. Основни типови: ишезавање (cross-fade) — глатко нестајање једног и појављивање другог; померање (slide) — један екран одлази, други долази; скалирање (scale/zoom) — елемент се повећава, отварајући детаљан екран. Комбиновани прелази спајају више ефеката.

Тип прелазаОписiOS APIAndroid API
Cross-fadeИшезавање: један садржај нестаје, други се појављујеUIView.transition(with:duration:options:.transitionCrossDissolve)TransitionSet + Fade()
SlideПомерање: садржај одлази/долази хоризонтално или вертикалноCATransition(type: .push, subtype: .fromLeft)Slide() / FragmentTransaction.setCustomAnimations
Scale / ZoomСкалирање: елемент се повећава на цео екранUIViewPropertyAnimator са scale анимацијомScale() + ActivityOptions.makeScaleUpAnimation
ExplodeРазлетање: садржај се распрши на делове при нестајањуCATransition(type: .reveal)Explode() (API 21+)
Fade-throughИшезавање кроз бели/црни екранUIView.transition(with: .transitionCrossDissolve, са белом позадином)Fade() кроз ChangeBounds

Правила Material Design: користите један тип прелаза у оквиру једне апликације за стварање јединственог визуелног језика. Препоручује се slide за навигацију између екрана истог нивоа (master → detail), cross-fade за смену садржаја унутар једног екрана (табови, пребацивање приказа), scale/zoom за прелаз од картице до детаљног екрана (картица производа → опис).

Transition у iOS (Swift)

На iOS UIView.transition је најједноставнији начин анимације смене садржаја унутар једног View. Подржава cross-dissolve, curl-up, curl-down, flip-from-left, flip-from-right. За навигационе прелазе између UIViewController користи се UINavigationControllerDelegate са UIViewControllerAnimatedTransitioning — ово даје потпуну контролу над анимацијом push/pop.

swift
import UIKit

// UIView.transition: промена слике са cross-dissolve
UIView.transition(with: imageView,
    duration: 0.4,
    options: [.transitionCrossDissolve, .curveEaseInOut]
) {
    self.imageView.image = UIImage(named: "new_image")
} completion: { _ in
    print("Transition завршен")
}

// UIView.transition: промена два View
UIView.transition(from: firstView, to: secondView,
    duration: 0.5,
    options: [.transitionFlipFromRight, .showHideTransitionViews]
) { _ in
    // firstView скривен, secondView приказан
}

// CATransition за слој (без 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 — модерна алтернатива за прилагођене прелазе на iOS 10+. За разлику од UIView.transition, PropertyAnimator подржава паузу, отказивање и reverse (обрнуту анимацију), што је важно за интерактивне прелазе (swipe-to-go-back). За анимацију између UIViewController користите UIPercentDrivenInteractiveTransition у пару са PropertyAnimator — ово је стандардни образац за интерактивну навигацију.

Transition у Android (Kotlin)

На Android FragmentTransaction са setCustomAnimations је основни начин анимације прелаза између Fragment. Параметри: enter (анимација уласка новог Fragment), exit (анимација изласка старог), popEnter и popExit — за повратну навигацију. FragmentTransaction подржава анимације ресурса (R.anim) и Transition Framework (R.transition).

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

// FragmentTransaction са анимацијама ресурса
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 са 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: анимација при покретању Activity
val options = ActivityOptions.makeScaleUpAnimation(
    view, 0, 0, view.width, view.height
).toBundle()
startActivity(intent, options)

Најбоље праксе Android: Slide() — за замену Fragment у навигацији (enter = Slide(Gravity.END), exit = Slide(Gravity.START)). Fade() — за приказивање/скривање overlay и дијалога. Explode() — за акцентоване прелазе (брисање елемента са листе). За старе уређаје (API < 21) користите R.anim као fallback. Transition Framework не подржава SurfaceView, TextureView, GLSurfaceView — за видео и камеру користите само анимације кроз R.anim.

Прилагођени прелази UIViewController у iOS

UIViewControllerAnimatedTransitioning — протокол iOS за креирање потпуно прилагођених анимација прелаза између контролера. Даје приступ контејнерском View (transitionContext.containerView), изворном и циљном View. У комбинацији са UIPercentDrivenInteractiveTransition овај приступ омогућава креирање интерактивних прелаза померањем прста.

swift
import UIKit

"> Кастомный аниматор перехода
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)
        }
    }
}

// Примена у UINavigationControllerDelegate
extension MainViewController: UINavigationControllerDelegate {
    func navigationController(
        _ nc: UINavigationController,
        animationControllerFor operation: UINavigationController.Operation,
        from: UIViewController, to: UIViewController
    ) -> UIViewControllerAnimatedTransitioning? {
        return ScaleTransitionAnimator(presenting: operation == .push)
    }
}

Интерактивни прелази: додајте UIPanGestureRecognizer на изворни екран. При активирању геста креирајте UIPercentDrivenInteractiveTransition и позовите update(CGFloat(percent)). За отказивање при недостизању прага (обично 30%) позовите cancel(). Овај образац се подразумевано користи у UINavigationController при pop гесту и у UIScrollView са pagingEnabled. За прилагођене гестове имплементирајте UIViewControllerInteractiveTransitioning.

Transition Framework у Android: сцена у сцену

Transition Framework (android.transition) — је декларативни систем анимације који аутоматски анимира промене између две сцене (Scene). Сцена је скуп View-ова са одређеним стањем. При прелазу са Scene A на Scene B, Transition Framework анализира разлику и анимира: промену позиције (ChangeBounds), промену величине (ChangeClipBounds, ChangeTransform), појављивање (Fade) и нестајање (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: комбинација ChangeBounds + Fade
val transition = TransitionSet().apply {
    ordering = TransitionSet.ORDERING_TOGETHER
    addTransition(ChangeBounds())
    addTransition(Fade(Fade.IN))
    duration = 400L
    interpolator = FastOutSlowInInterpolator()
}

// Прелаз између сцена у 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 без ручной настройки
TransitionManager.go(scene2, AutoTransition().apply {
    duration = 350L
})

// TransitionManager.beginDelayedTransition — без сцена
TransitionManager.beginDelayedTransition(sceneRoot, ChangeBounds())
itemView.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
itemView.requestLayout() "> Изменение layout анимируется автоматически

ChangeBounds — најчешће коришћени прелаз у Android, анимира промену положаја и величине View. ChangeTransform анимира rotation и scale. ChangeImageTransform — за анимацију ImageView (centerCrop → fitCenter). За сложене прелазе са променом структуре хијерархије користите TransitionSet са ordering = ORDERING_SEQUENTIAL (анимације се извршавају редом, не паралелно). Према документацији Android Developers (2026), Transition Framework подржава све стандардне View, али не подржава анимацију површине (SurfaceView, TextureView, VideoView).

Често постављана питања

Која је разлика између Transition и Animation?

Animation — анимација својстава једног објекта (alpha, translation, scale). Transition — анимација смене скупа објеката или стања (фрагмент → фрагмент, сцена → сцена). Transition управља вишеструким променама истовремено: појављивање, нестајање, премештање, промена величине — и аутоматски анимира разлику између два стања. Animation захтева ручно управљање сваким својством.

Како направити гладак прелаз између фрагмената Android?

Користите FragmentTransaction.setCustomAnimations са Transition Framework: fragment1.exitTransition = Fade(Fade.OUT), fragment2.enterTransition = Slide(Gravity.END). За секвенцу: setReorderingAllowed(true) — фрагменти ће бити преуређени за гладак паралелни прелаз. За једноставне случајеве довољно је slide_in_right / slide_out_left из R.anim. За повратну навигацију наведите popEnter и popExit.

Transition Framework не анимира промену висине View — шта радити?

Transition Framework анимира само својства која не изазивају прерачун layout-а. За анимацију висине користите ChangeBounds — он аутоматски анимира промену граница View-а између два layout стања. Позовите TransitionManager.beginDelayedTransition(viewGroup, ChangeBounds()) пре промене LayoutParams. Ако се висина мења кроз WRAP_CONTENT, уверите се да је layout_height пре и после различит — ChangeBounds неће радити ако су оба стања match_parent.

Како направити прилагођени прелаз у SwiftUI?

Користите модификатор .transition() са AnyTransition: .transition(.move(edge: .trailing).combined(with: .opacity)). За прилагођене прелазе имплементирајте AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)). За анимацију унутар NavigationStack користите .navigationTransition(.slide) у iOS 18+. SwiftUI не подржава UIViewControllerAnimatedTransitioning — само декларативне прелазе кроз AnyTransition.

Како измерити перформансе Transition?

Користите Profile GPU Rendering (Android) или Core Animation Instrument (iOS). За Android додајте профилисање Transition кроз adb shell setprop debug.transition.profiling 1 — у логовима ће се појавити трајања сваке фазе прелаза. На iOS укључите Slow Animations у симулатору. Циљне метрике: трајање < 400 ms, FPS >= 55, frame drops — не више од 2 по прелазу. За сложене сцене са 15+ истовремено анимираних View-ова користите ChangeBounds са duration 300 ms.

Резиме

  • Transition — анимација смене садржаја између екрана, фрагмената или стања интерфејса.
  • UIView.transition (iOS) — основни API за cross-dissolve, flip, curl прелазе унутар View.
  • UIViewControllerAnimatedTransitioning (iOS) — протокол за прилагођене прелазе између контролера.
  • FragmentTransaction.setCustomAnimations (Android) — анимација прелаза између Fragment.
  • Transition Framework (android.transition) — декларативни систем сцена: ChangeBounds, Fade, Slide, Explode.
  • Препоручено трајање: 300–400 ms за мобилне, до 600 ms за велике елементе.
  • Један тип прелаза по апликацији за јединствени визуелни језик (Material Design).

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође