Transition (geçiş animasyonu), bir içeriği başka bir içerikle görsel olarak değiştiren bir mekanizmadır: ekranlar, fragmentler, view'lar veya arayüz durumları. Doğru şekilde uygulanan bir geçiş, kullanıcının dikkatini yönlendirir, öğeler arasındaki ilişkiyi açıklar ve gezinmeyi sezgisel hale getirir. Material Design Guidelines'a (2026) göre, iyi tasarlanmış geçişlere sahip uygulamalar, ikinci seansta %22 daha yüksek kullanıcı tutma oranı gösterir. Diğer animasyon türleri hakkında daha fazla bilgi için genel animasyon rehberine bakın.
Önemli Noktalar
Transition, bir görsel arayüz durumunun başka bir durumla değiştirilmesi sırasında oluşan bir animasyondur. Property Animation'dan (tek bir nesnenin özelliğini canlandırma) farklı olarak, Transition bir dizi değişikliği yönetir: öğelerin görünmesi/kaybolması, konumlarının, boyutlarının ve özelliklerinin tek bir geçiş içinde değiştirilmesi. Transition, kullanıcının neyin nereye taşındığını anlaması için içerik değişimini sorunsuz bir şekilde çözer.
Mobil platformlarda, Transition üç ana senaryoda kullanılır: ekranlar arasında gezinme (push, pop, modal present), fragment değişiklikleri (Android FragmentTransaction) ve ekran içi durum değişiklikleri (kart genişletme, sekme değiştirme). Her senaryo kendi yaklaşımını gerektirir: gezinme geçişleri — iOS'ta UIViewControllerAnimatedTransitioning veya Android'te ActivityOptions, ekran içi geçişler — Transition Framework veya UIView.transition.
Apple HIG'ye (2026) göre, standart bir geçişin süresi 400–500 ms'yi geçmemelidir — daha uzun animasyonlar gecikme olarak algılanır. Material Design, mobil geçişler için 300–350 ms önerir. Büyük öğeler (kartlar, resimler) için süre, algılanan performans kaybı olmadan 500–600 ms'ye kadar artırılabilir.
Geçiş türleri, hangi içeriğin nasıl değiştiğine bağlı olarak birkaç kategoriye ayrılır. Temel türler: cross-fade — birinin yumuşak bir şekilde kaybolması ve diğerinin görünmesi; slide — bir ekran dışarı çıkar, diğeri içeri girer; scale/zoom — bir öğe büyüyerek ayrıntılı bir ekran açar. Birleşik geçişler birden çok efekti birleştirir.
| Geçiş Türü | Açıklama | iOS API | Android API |
|---|---|---|---|
| Cross-fade | Sönümlenme: bir içerik kaybolur, diğeri belirir | UIView.transition(with:duration:options:.transitionCrossDissolve) | TransitionSet + Fade() |
| Slide | Kaydırma: içerik yatay veya dikey olarak içeri/dışarı girer | CATransition(type: .push, subtype: .fromLeft) | Slide() / FragmentTransaction.setCustomAnimations |
| Scale / Zoom | Ölçekleme: öğe tam ekrana büyür | UIViewPropertyAnimator ölçek animasyonuyla | Scale() + ActivityOptions.makeScaleUpAnimation |
| Explode | Patlama: içerik kaybolurken parçalara ayrılır | CATransition(type: .reveal) | Explode() (API 21+) |
| Fade-through | Beyaz/siyah ekran üzerinden sönümlenme | UIView.transition(with: .transitionCrossDissolve, beyaz arka planla) | ChangeBounds aracılığıyla Fade() |
Material Design Kuralları: birleşik bir görsel dil oluşturmak için tek bir uygulama içinde bir geçiş türü kullanın. Önerilen: aynı seviyedeki ekranlar arasında gezinme için slide (ana → detay), bir ekran içinde içerik değişimi için cross-fade (sekmeler, görünüm değiştirme), karttan detay ekranına geçiş için scale/zoom (ürün kartı → açıklama).
iOS'ta, UIView.transition tek bir View içinde içerik değişikliklerini canlandırmanın en basit yoludur. Cross-dissolve, curl-up, curl-down, flip-from-left, flip-from-right'ı destekler. UIViewController arasındaki gezinme geçişleri için, UIViewControllerAnimatedTransitioning ile birlikte UINavigationControllerDelegate kullanın — bu, push/pop animasyonu üzerinde tam kontrol sağlar.
import UIKit
// UIView.transition: cross-dissolve ile görüntü değişimi
UIView.transition(with: imageView,
duration: 0.4,
options: [.transitionCrossDissolve, .curveEaseInOut]
) {
self.imageView.image = UIImage(named: "new_image")
} completion: { _ in
print("Transition completed")
}
// UIView.transition: iki görünümün değiştirilmesi
UIView.transition(from: firstView, to: secondView,
duration: 0.5,
options: [.transitionFlipFromRight, .showHideTransitionViews]
) { _ in
// firstView gizli, secondView gösteriliyor
}
// CATransition katman için (Auto Layout olmadan)
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+ üzerinde özel geçişler için modern bir alternatiftir. UIView.transition'dan farklı olarak PropertyAnimator, duraklatma, iptal ve ters animasyonu destekler; bu, etkileşimli geçişler (geri gitmek için kaydırma) için önemlidir. UIViewController'lar arasında animasyon için, PropertyAnimator ile birlikte UIPercentDrivenInteractiveTransition kullanın — bu, etkileşimli gezinme için standart kalıptır.
Android'te, FragmentTransaction ile setCustomAnimations, Fragment'ler arasındaki geçişleri canlandırmanın ana yoludur. Parametreler: enter (yeni Fragment'in giriş animasyonu), exit (eski Fragment'in çıkış animasyonu), popEnter ve popExit — geri gezinme için. FragmentTransaction, animasyon kaynaklarını (R.anim) ve Transition Framework'ü (R.transition) destekler.
import androidx.fragment.app.FragmentTransaction
import androidx.transition.TransitionInflater
// FragmentTransaction kaynak animasyonlarıyla
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 ile
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 başlatılırken animasyon
val options = ActivityOptions.makeScaleUpAnimation(
view, 0, 0, view.width, view.height
).toBundle()
startActivity(intent, options)
Android En İyi Uygulamaları: Slide() — gezinmede Fragment değiştirme için (enter = Slide(Gravity.END), exit = Slide(Gravity.START)). Fade() — bindirmeleri ve diyalogları gösterme/gizleme için. Explode() — vurgu geçişleri için (bir öğeyi listeden silme). Eski cihazlar (API < 21) için R.anim kaynaklarını yedek olarak kullanın. Transition Framework, SurfaceView, TextureView, GLSurfaceView'ı desteklemez — video ve kamera için yalnızca R.anim animasyonlarını kullanın.
UIViewControllerAnimatedTransitioning, görünüm denetleyicileri arasında tamamen özel geçiş animasyonları oluşturmak için bir iOS protokolüdür. Kapsayıcı görünüme (transitionContext.containerView), kaynak ve hedef görünümlere erişim sağlar. UIPercentDrivenInteractiveTransition ile birleştirildiğinde, bu yaklaşım parmak kaydırma ile etkileşimli geçişler oluşturmaya olanak tanır.
import UIKit
"> Özel geçiş animatörü
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'de uygulama
extension MainViewController: UINavigationControllerDelegate {
func navigationController(
_ nc: UINavigationController,
animationControllerFor operation: UINavigationController.Operation,
from: UIViewController, to: UIViewController
) -> UIViewControllerAnimatedTransitioning? {
return ScaleTransitionAnimator(presenting: operation == .push)
}
}
Etkileşimli geçişler: kaynak ekrana bir UIPanGestureRecognizer ekleyin. Hareket tetiklendiğinde, bir UIPercentDrivenInteractiveTransition oluşturun ve update(CGFloat(percent)) çağırın. Eşiğe (genellikle %30) ulaşılmadığında iptal etmek için cancel() çağırın. Bu kalıp, UINavigationController'da pop hareketleri için ve pagingEnabled ile UIScrollView'da varsayılan olarak kullanılır. Özel hareketler için UIViewControllerInteractiveTransitioning'i uygulayın.
Transition Framework (android.transition), iki sahne (Scene) arasındaki değişiklikleri otomatik olarak canlandıran bildirimsel bir animasyon sistemidir. Sahne, belirli bir duruma sahip bir Views kümesidir. Sahne A'dan Sahne B'ye geçerken, Transition Framework farkı analiz eder ve canlandırır: konum değişikliği (ChangeBounds), boyut değişikliği (ChangeClipBounds, ChangeTransform), görünme (Fade) ve kaybolma (Fade).
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 kombinasyonu
val transition = TransitionSet().apply {
ordering = TransitionSet.ORDERING_TOGETHER
addTransition(ChangeBounds())
addTransition(Fade(Fade.IN))
duration = 400L
interpolator = FastOutSlowInInterpolator()
}
// Bir ViewGroup'da sahneler arası geçiş
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)
"> Manuel ayar gerektirmeyen AutoTransition
TransitionManager.go(scene2, AutoTransition().apply {
duration = 350L
})
// TransitionManager.beginDelayedTransition — sahnesiz
TransitionManager.beginDelayedTransition(sceneRoot, ChangeBounds())
itemView.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
itemView.requestLayout() "> Layout değişikliği otomatik olarak animasyonlanır
ChangeBounds, Android'te en çok kullanılan geçiştir, View'ın konum ve boyut değişikliklerini canlandırır. ChangeTransform, dönüş ve ölçeği canlandırır. ChangeImageTransform — ImageView animasyonu için (centerCrop → fitCenter). Hiyerarşi yapısında değişiklik olan karmaşık geçişler için, ordering = ORDERING_SEQUENTIAL ile TransitionSet kullanın (animasyonlar paralel değil sırayla yürütülür). Android Developers (2026) belgelerine göre, Transition Framework tüm standart View'ları destekler ancak yüzey animasyonunu (SurfaceView, TextureView, VideoView) desteklemez.
Sıkça Sorulan Sorular
Animation — tek bir nesnenin özelliklerini (alpha, translation, scale) canlandırır. Transition — bir dizi nesnenin veya durumun değişimini canlandırır (fragment → fragment, scene → scene). Transition, birden çok değişikliği aynı anda yönetir: görünme, kaybolma, hareket, boyut değişikliği — ve iki durum arasındaki farkı otomatik olarak canlandırır. Animation, her özelliğin manuel olarak yönetilmesini gerektirir.
Transition Framework ile FragmentTransaction.setCustomAnimations kullanın: fragment1.exitTransition = Fade(Fade.OUT), fragment2.enterTransition = Slide(Gravity.END). Sıralama için: setReorderingAllowed(true) — fragment'ler yumuşak paralel geçiş için yeniden sıralanır. Basit durumlar için R.anim'den slide_in_right / slide_out_left yeterlidir. Geri gezinme için popEnter ve popExit'i belirtin.
Transition Framework yalnızca yerleşim yeniden hesaplamasını tetiklemeyen özellikleri canlandırır. Yükseklik animasyonu için ChangeBounds kullanın — iki yerleşim durumu arasındaki View sınır değişikliklerini otomatik olarak canlandırır. LayoutParams'ı değiştirmeden önce TransitionManager.beginDelayedTransition(viewGroup, ChangeBounds()) çağırın. Yükseklik WRAP_CONTENT ile değişiyorsa, layout_height'in önce ve sonra farklı olduğundan emin olun — her iki durum da match_parent ise ChangeBounds çalışmaz.
AnyTransition ile .transition() değiştiricisini kullanın: .transition(.move(edge: .trailing).combined(with: .opacity)). Özel geçişler için AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)) uygulayın. NavigationStack içinde animasyon için iOS 18+ üzerinde .navigationTransition(.slide) kullanın. SwiftUI, UIViewControllerAnimatedTransitioning'i desteklemez — yalnızca AnyTransition aracılığıyla bildirimsel geçişler.
Profile GPU Rendering (Android) veya Core Animation Instrument (iOS) kullanın. Android için, adb shell setprop debug.transition.profiling 1 ile Transition Profiling'i etkinleştirin — günlükler her geçiş aşamasının süresini gösterir. iOS'ta, simülatörde Slow Animations'ı etkinleştirin. Hedef metrikler: süre < 400 ms, FPS >= 55, kare düşüşü — geçiş başına en fazla 2. 15+ eşzamanlı animasyonlu View içeren karmaşık sahneler için 300 ms süreyle ChangeBounds kullanın.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun