Transition: مبانی، انیمیشن انتقال در برنامه‌های موبایل

نویسنده: IT Sectr منتشر شده: 2026-03-02 زمان مطالعه: 11 دقیقه

Transition (انیمیشن انتقال) — مکانیزم تغییر بصری یک محتوا به دیگری: صفحه‌ها، فرگمنت‌ها، ویوها یا حالت‌های رابط کاربری. یک انتقال به‌درستی پیاده‌سازی‌شده توجه کاربر را هدایت می‌کند، رابطه بین عناصر را توضیح می‌دهد و ناوبری را بصری می‌سازد. طبق Material Design Guidelines (2026)، برنامه‌هایی با انتقال‌های حساب‌شده ۲۲٪ حفظ کاربر در جلسه دوم را نشان می‌دهند. درباره سایر انواع انیمیشن در راهنمای کلی انیمیشن بخوانید.

نکات اصلی

  • Transition — انیمیشن تغییر محتوا بین صفحه‌ها، فرگمنت‌ها یا حالت‌ها.
  • UIView.transition — API اصلی برای انیمیشن انتقال در iOS (UIKit).
  • FragmentTransaction.setCustomAnimations — تنظیم انیمیشن انتقال بین Fragment در Android.
  • Transition Framework (android.transition) — سیستم انیمیشن declarative 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)، مدت زمان انتقال استاندارد نباید از ۴۰۰–۵۰۰ میلی‌ثانیه تجاوز کند — انیمیشن‌های طولانی‌تر به عنوان تأخیر درک می‌شوند. Material Design برای انتقال‌های موبایل ۳۰۰–۳۵۰ میلی‌ثانیه را توصیه می‌کند. برای عناصر بزرگ (کارت‌ها، تصاویر) زمان می‌تواند بدون کاهش عملکرد درک‌شده تا ۵۰۰–۶۰۰ میلی‌ثانیه افزایش یابد.

انواع انیمیشن‌های انتقال

انواع انتقال بسته به این که چه محتوایی و چگونه تغییر می‌کند به چند دسته تقسیم می‌شوند. انواع پایه: محوشدگی (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 با انیمیشن scaleScale() + ActivityOptions.makeScaleUpAnimation
Explodeانفجار: محتوا هنگام ناپدید شدن به تکه‌ها تقسیم می‌شودCATransition(type: .reveal)Explode() (API 21+)
Fade-throughمحوشدگی از طریق صفحه سفید/سیاهUIView.transition(with: .transitionCrossDissolve, با پس‌زمینه سفید)Fade() از طریق ChangeBounds

قوانین Material Design: برای ایجاد یک زبان بصری واحد از یک نوع انتقال در یک برنامه استفاده کنید. slide برای ناوبری بین صفحه‌های هم‌سطح (master → detail)، cross-fade برای تغییر محتوا در یک صفحه (تب‌ها، تغییر view)، 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 (انیمیشن خروج Fragment قدیمی)، 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)) را فراخوانی کنید. برای لغو در صورت عدم رسیدن به آستانه (معمولاً ۳۰٪) cancel() را فراخوانی کنید. این الگو به طور پیش‌فرض در UINavigationController در ژست pop و در UIScrollView با pagingEnabled استفاده می‌شود. برای ژست‌های سفارشی UIViewControllerInteractiveTransitioning را پیاده‌سازی کنید.

Transition Framework در Android: صحنه به صحنه

Transition Framework (android.transition) — یک سیستم انیمیشن declarative است که به طور خودکار تغییرات بین دو صحنه (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 را انیمیشن می‌کند. قبل از تغییر LayoutParams، TransitionManager.beginDelayedTransition(viewGroup, ChangeBounds()) را فراخوانی کنید. اگر ارتفاع از طریق WRAP_CONTENT تغییر می‌کند، مطمئن شوید که layout_height قبل و بعد متفاوت است — اگر هر دو حالت match_parent باشند، ChangeBounds کار نخواهد کرد.

چگونه یک انتقال سفارشی در SwiftUI ایجاد کنیم؟

از اصلاح‌کننده .transition() با AnyTransition استفاده کنید: .transition(.move(edge: .trailing).combined(with: .opacity)). برای انتقال‌های سفارشی AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)) را پیاده‌سازی کنید. برای انیمیشن داخل NavigationStack در iOS 18+ از .navigationTransition(.slide) استفاده کنید. SwiftUI از UIViewControllerAnimatedTransitioning پشتیبانی نمی‌کند — فقط انتقال‌های declarative از طریق AnyTransition.

چگونه عملکرد Transition را اندازه‌گیری کنیم؟

از Profile GPU Rendering (Android) یا Core Animation Instrument (iOS) استفاده کنید. برای Android پروفایل Transition را از طریق adb shell setprop debug.transition.profiling 1 اضافه کنید — در لاگ‌ها مدت زمان هر مرحله از انتقال ظاهر می‌شود. در iOS Slow Animations را در شبیه‌ساز فعال کنید. معیارهای هدف: مدت زمان < ۴۰۰ میلی‌ثانیه، FPS >= ۵۵، frame drops — حداکثر ۲ در هر انتقال. برای صحنه‌های پیچیده با ۱۵+ View که همزمان انیمیشن می‌شوند از ChangeBounds با duration ۳۰۰ میلی‌ثانیه استفاده کنید.

خلاصه

  • Transition — انیمیشن تغییر محتوا بین صفحه‌ها، فرگمنت‌ها یا حالت‌های رابط کاربری.
  • UIView.transition (iOS) — API پایه برای انتقال‌های cross-dissolve، flip، curl در داخل View.
  • UIViewControllerAnimatedTransitioning (iOS) — پروتکل برای انتقال‌های سفارشی بین کنترلرها.
  • FragmentTransaction.setCustomAnimations (Android) — انیمیشن انتقال بین Fragment.
  • Transition Framework (android.transition) — سیستم صحنه declarative: ChangeBounds, Fade, Slide, Explode.
  • مدت زمان توصیه‌شده: ۳۰۰–۴۰۰ میلی‌ثانیه برای موبایل، تا ۶۰۰ میلی‌ثانیه برای عناصر بزرگ.
  • یک نوع انتقال در هر برنامه برای زبان بصری واحد (Material Design).

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید