Önemli Noktalar
Timeline, bir animasyonun ne zaman başlayacağını, ne kadar süreceğini ve zamanın ilerlemesinin animasyonlu parametredeki değişikliklere nasıl dönüştürüleceğini tanımlayan bir animasyon zaman modelidir. Her karenin manuel olarak ayarlandığı kare kare (frame-by-frame) animasyonun aksine, zaman çizelgesi animasyonu parametrelerle tanımlanır: duration — toplam süre, startDelay — başlamadan önceki gecikme, repeatCount — tekrar sayısı ve timingFunction — hız eğrisi.
Zaman çizelgesi normalleştirilmiş alan [0, 1] — yerel zaman veya ilerleme içinde çalışır. Sıfır değeri animasyonun başlangıcına, bir ise tamamlanmaya karşılık gelir. Bir ease (yumuşatma) işlevi, doğrusal yerel zamanı gerçek animasyon ilerlemesine dönüştürür. repeatCount > 1 ise, zaman çizelgesi döngüye girer (RESTART) veya tersine döner (REVERSE). iOS'ta CAMediaTiming, speed (oynatma hızı, >1 hızlandırır) ve timeOffset (zaman çizelgesi kaydırma) ekler. Android'de Animator, doğrudan zaman çizelgesi konum kontrolü için setCurrentPlayTime() kullanır. Material Design'a göre, 100 ms'den kısa animasyonlar animasyon olarak algılanmazken, 500 ms'den uzun olanlar rahatsız etmeye başlar. Arayüz animasyonları için en uygun süre 200–350 ms'dir.
iOS'ta animasyon zaman çizelgesi yönetimi, CAAnimation ve CALayer tarafından uygulanan CAMediaTiming protokolü aracılığıyla gerçekleştirilir. Şu özellikleri sağlar: duration (saniye cinsinden), beginTime (üst zaman çizelgesine göre başlangıç zamanı), repeatCount (tekrar sayısı), repeatDuration (toplam tekrar süresi), autoreverses (otomatik tersine çevirme), fillMode (animasyon öncesi/sonrası davranış), speed (oynatma hızı) ve timeOffset (zaman çizelgesi kaydırma).
CACurrentMediaTime(), cihazın son yeniden başlatılmasından bu yana saniye cinsinden mutlak zamanı döndüren bir işlevdir. Birden çok animasyonu senkronize etmek için temel zaman damgası olarak kullanılır: hassas gecikmeli bir animasyon grubu başlatmak için beginTime = CACurrentMediaTime() + offset olarak ayarlayın. CAMediaTiming ayrıca zaman çizelgesi hiyerarşisini de destekler — bir üst katman, speed özelliği aracılığıyla tüm alt animasyonları hızlandırabilir/yavaşlatabilir. UIKit'te, UIViewPropertyAnimator (iOS 10+), duration, delay özellikleri ve startAnimation/pauseAnimation/stopAnimation geri çağırmaları aracılığıyla zaman çizelgesini soyutlar. SwiftUI'de, Animation yapısı, animasyon belirtiminin bir parçası olarak duration sağlar, ancak doğrudan zaman çizelgesi kontrolü gizlidir — özel zaman çizelgesi için özel bir zamanlayıcı ile TimelineView (iOS 15+) kullanın.
Android'de zaman çizelgesi yönetimi, Animator sınıfı ve alt sınıflarında (ValueAnimator, ObjectAnimator) merkezileştirilmiştir. Ana zaman çizelgesi özellikleri şunlardır: duration (milisaniye cinsinden), startDelay (başlamadan önceki gecikme), repeatCount (tekrar sayısı), repeatMode (RESTART veya REVERSE). setCurrentPlayTime(long) yöntemi, zaman çizelgesinde herhangi bir konuma gezinmeye izin verir.
ValueAnimator bir soyutlama katmanı ekler: duration'a dayalı olarak 0'dan 1'e (normalleştirilmiş zaman) değerler üretir ve bunları TimeInterpolator'a iletir. AnimatorSet, sıralı (playSequentially) veya paralel (playTogether) yürütme ile birden çok Animator'ı tek bir zaman çizelgesinde birleştirmeye izin verir. Jetpack Compose'da zaman çizelgesi AnimationSpec aracılığıyla yönetilir: tween (durationMillis, delayMillis, easing), spring (dampingRatio, stiffness) ve keyframes (her bölüm için özel easing ile zaman çizelgesindeki noktalar). Compose AnimatedContent, transitionSpec için bir zaman çizelgesi kullanır — geliştirici, içeriğin zaman kaymalarıyla nasıl görünüp kaybolduğunu açıklar. Android Performance'a göre, 60fps için animasyon zaman çizelgesi 16 ms'nin (vsync döngüsü) katı olmalıdır — yanlış süre, ekran yenileme hızıyla uyumsuzluk nedeniyle kare düşüşlerine neden olabilir.
Birden çok animasyon oluştururken zaman çizelgesi özellikle önemli hale gelir. Üç temel desen: basamaklı (cascade) — animasyonlar bir kayma ile sırayla başlar (her biri bir öncekinden bir offset sonra başlar), paralel — tüm animasyonlar aynı zaman çizelgesiyle aynı anda başlar ve kademeli (stagger) — animasyonlar örtüşerek başlar (ikincisi, birincisi tamamlanmadan başlar).
iOS'ta basamaklı, her CAAnimation'un beginTime = önceki beginTime + önceki duration aracılığıyla uygulanır. Kademeli için, iç içe animasyonlarda farklı beginTime değerlerine sahip CAAnimationGroup kullanılır. Android'de AnimatorSet, playSequentially ve playTogether'ı destekler; her Animator için startDelay ayarlanarak kademeli oluşturulur. Compose'da, AnimatedVisibility, enter/exitTransition ile liste öğelerinin basamaklı görünümü için staggerChildren varyantında kademeli kullanır. WWDC ve Google I/O 2024'te her iki platform da zaman çizelgesi görselleştirme araçlarını tanıttı: Xcode Animations Inspector ve Android Studio Animations Timeline — gerçek zamanlı olarak gerçek zaman çizelgesini ve düşen kareleri gösterir.
Özel zaman çizelgesine sahip bir animasyon örneği: 0,3 saniye gecikme, 0,6 saniye süre, otomatik tersine çevirme ve sonsuz tekrar. CAMediaTiming tüm zaman parametrelerini kontrol eder.
import UIKit
func breathingAnimation(layer: CALayer) {
let animation = CABasicAnimation(keyPath: "opacity")
animation.duration = 0.6
animation.beginTime = CACurrentMediaTime() + 0.3
animation.fromValue = 1.0
animation.toValue = 0.3
animation.autoreverses = true
animation.repeatCount = .infinity
animation.speed = 1.0
animation.fillMode = .both
layer.add(animation, forKey: "breathing")
}
beginTime = CACurrentMediaTime() + 0,3, 300 ms'lik bir gecikme sağlar. autoreverses = true, animasyonun her döngüden sonra ters yönde çalışmasını sağlar. repeatCount = .infinity, “nefes alma” efekti için sonsuz bir döngü oluşturur. speed = 1,0 — normal hız; 2,0 değeriyle animasyonu 2 kat hızlandırın.
SwiftUI TimelineView (iOS 15+), özel animasyon için sistem zaman çizelgesine erişim sağlar. Görünüm, zamanlayıcının her tikinde güncellenir.
import SwiftUI
struct TimelineViewExample: View {
var body: some View {
TimelineView(.periodic(from: .now, by: 0.1)) { context in
let seconds = context.date.timeIntervalSinceReferenceDate
let phase = sin(seconds * 2 * .pi)
Circle()
.fill(Color.blue)
.frame(width: 60 + 30 * phase)
.animation(.linear(duration: 0), value: phase)
}
}
}
TimelineView, .periodic zamanlayıcısı ile her 0,1 saniyede bir tik üretir. Closure içinde context.date, sinüs dalgası fazına dönüştürülen geçerli saattir. Dairenin boyutu 1 Hz frekansında atar. TimelineView, Animation API'si olmadan SwiftUI'de kendi zaman çizelgesine sahip bir animasyon oluşturmanın tek yoludur.
Tam zaman çizelgesi kontrolüne sahip ValueAnimator: gecikme, süre, tekrar. setCurrentPlayTime yöntemi, zaman çizelgesi boyunca atlamaya izin verir.
import android.animation.ValueAnimator
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.View
fun View.timelineAnimation() {
ValueAnimator.ofFloat(0f, 1f).apply {
duration = 400
startDelay = 200
repeatCount = 2
repeatMode = ValueAnimator.REVERSE
interpolator = AccelerateDecelerateInterpolator()
addUpdateListener { animator ->
val progress = animator.animatedFraction
alpha = progress
translationX = progress * 100f
}
start()
}
}
startDelay = 200 ms — başlamadan önceki gecikme. repeatMode = REVERSE, animasyonu başlangıç değerine döndürür. animatedFraction, repeatMode'u hesaba katarak 0'dan 1'e ilerleme sağlar. addUpdateListener her karede (genellikle 16 ms) tetiklenir. Duraklatmak için pause() / resume() kullanın.
AnimatorSet, birden çok animasyondan karmaşık zaman çizelgeleri oluşturmaya izin verir. Örnek, örtüşme (kademeli) ile sıralı yürütmeyi gösterir.
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.view.View
fun View.staggerAnimation() {
val fadeIn = ObjectAnimator.ofFloat(this, "alpha", 0f, 1f).apply {
duration = 300
}
val slideUp = ObjectAnimator.ofFloat(this, "translationY", 100f, 0f).apply {
duration = 400
startDelay = 100
}
val scale = ObjectAnimator.ofFloat(this, "scaleX", 0.8f, 1f).apply {
duration = 250
startDelay = 200
}
AnimatorSet().apply {
playTogether(fadeIn, slideUp, scale)
start()
}
}
playTogether tüm animasyonları paralel olarak başlatır, ancak her birinin kendi startDelay değeri vardır — bu bir kademeli efekt oluşturur: fadeIn önce başlar (0 ms), slideUp 100 ms sonra, scale 200 ms sonra. Sonuçtaki zaman çizelgesi: 0 — 100 — 200 — 600 ms. Sıralı yürütme için playSequentially kullanın.
Sıkça Sorulan Sorular
Animator, tüm animasyonlar için soyut bir temel sınıftır. ValueAnimator, bir nesneye bağlanmadan sayısal değerleri canlandıran alt sınıfıdır. ObjectAnimator (ValueAnimator'ın bir alt sınıfı), bir nesnenin belirli bir özelliğini (örneğin alpha veya translationY) canlandırır. Zaman çizelgesi için, addUpdateListener aracılığıyla geri çağırmalı evrensel bir zamanlayıcı olarak ValueAnimator kullanın.
İlerlemeyi hesaplamak için kare sayısı yerine sistem saatlerini (iOS'ta CACurrentMediaTime, Android'de System.nanoTime) kullanın. Ağ senkronizasyonu için, offset düzeltmeli NTP tabanlı bir zamanlayıcı kullanın. iOS, milisaniye hassasiyetinde ses-video zaman çizelgesi senkronizasyonu için AVAudioSession'ı destekler. Kare tabanlı senkronizasyondan kaçının — kare hızları 30 ila 120 fps arasında değişir.
startOffset, milisaniye cinsinden animasyon başlamadan önceki gecikmedir. Basamaklı ve kademeli efektler için kullanılır. repeatCount tekrar sayısıdır: 0 = tekrar yok, ValueAnimator.INFINITE = sonsuz döngü. repeatMode yönü belirler: RESTART (başa sıfırlama) veya REVERSE (ters yön). iOS'ta startOffset, beginTime olarak adlandırılır (CACurrentMediaTime ile kombinasyon halinde), repeatCount ise CABasicAnimation'un aynı özelliğidir.
Material Design, arayüz animasyonları için 200–350 ms önerir. 100 ms'den kısa animasyonlar animasyon olarak algılanmazken, 500 ms'den uzun olanlar rahatsız edicidir. Öğelerin giriş/çıkışı için: 200–300 ms. Ekranlar arası geçişler için: 300–400 ms. Küçük öğeler için daha kısa süreler (100–200 ms) ve büyük öğeler için daha uzun süreler (400–500 ms) kullanın.
Sarsıntı (jank) şunlardan kaynaklanır: ana iş parçacığındaki uzun süreli işlemler (işlemeyi engeller), overdraw ile karmaşık View/Layer hiyerarşisi veya yanlış zaman çizelgesi kullanımı (sürenin vsync'in katı olmaması — 60fps için 16ms, 120fps için 8ms). Düşen kareleri tespit etmek için Xcode Instruments Animations veya Android Studio Profiler kullanın. Compose'da karmaşık çizimleri önbelleğe almak için Modifier.drawWithCache 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