Hareket Navigasyonu, çoğu modern akıllı telefonda donanım düğmelerinin yerini alan, dokunma hareketleri aracılığıyla bir mobil uygulamayı kontrol etme sistemidir. Android Developers (2024)'a göre, Android 10'dan itibaren hareket navigasyonu standart haline gelirken, Apple 2017'de iPhone X ile hareketlere geçti. Sistem kaydırma, sıkıştırma, çift dokunma ve uzun basmayı içerir — her hareketin ekran bağlamında belirli bir amacı vardır. Anlamak hareket navigasyonunun mimarisini anlamak, sezgisel ve duyarlı arayüzler oluşturmak için gereklidir.
Önemli Noktalar
Hareket Navigasyonu, dokunmatik ekran tarafından tanınan dokunma, hareket ve basma dizileri aracılığıyla kullanıcının mobil cihazla etkileşim kurma yöntemidir. Geleneksel düğmelerin aksine, hareketler ekranda sabit bir konuma sahip değildir ve hareket desenleriyle tanınır: kenardan kaydırma, iki parmakla sıkıştırma, uzun basma.
Hareket navigasyonuna geçiş iPhone X ile başladı (2017), Apple Ana Sayfa düğmesini tamamen kaldırarak yerine alt kenardan kaydırmayı getirdi. Google, Android 10 (2020) ile bu trendi takip ederek kullanıcılara seçenek sundu: üç düğmeli navigasyon, iki düğmeli navigasyon ve tam hareket navigasyonu. StatCounter (2025)'e göre, Android cihazların %75'inden fazlası ve iOS cihazların %95'i hareket navigasyonu kullanıyor.
Mimari olarak, hareket tanıma üç aşamadan oluşur: Yakalama (dokunma olaylarını yakalama), Tanıma (hareket desenini belirleme) ve Eylem (atanan eylemi gerçekleştirme). Sistem düzeyinde, Android ve iOS temel navigasyon hareketleri için yerleşik işleyicilere sahiptir — geri kaydırma, ana ekrana gitme, uygulama değiştiriciyi açma. Geliştiricinin yalnızca kendi hareketlerini bu sisteme doğru şekilde entegre etmesi gerekir.
Tüm dokunma hareketleri amaç ve yürütme yöntemine göre üç kategoriye ayrılabilir. Her türün kendi işleme kuralları ve arayüzde kullanım için önerileri vardır.
Navigasyon hareketleri ekranlar arasındaki hareketi kontrol eder: geri dönmek için sol kenardan kaydırma (iOS), uygulama değiştiriciyi açmak için yukarı kaydırma, ana ekrana dönmek için alt kenardan kaydırma. Bu hareketler pencere düzeyinde sistem tarafından işlenir ve uygulama içindeki özel hareketlerle çakışmamalıdır.
Manipülasyon hareketleri ekrandaki nesnelerin konumunu, boyutunu veya yönünü değiştirir. Sıkıştırma (iki parmakla yakınlaştırma), döndürme, sürükleme, hızlı kaydırma — tüm bu hareketler View veya Composable düzeyinde işlenir ve sistem navigasyonunu etkilemez.
Bağlamsal hareketler başka bir ekrana gitmeden ek işlevleri etkinleştirir. Uzun basma (bağlam menüsü için), çift dokunma (beğeni veya yakınlaştırma için), kenar kaydırma (Drawer açmak için). Bu hareketler sistem navigasyon hareketleriyle örtüşebileceğinden en dikkatli uygulamayı gerektirir.
| Hareket Türü | Örnek | İşleme Düzeyi | Sistem Çakışması |
|---|---|---|---|
| Navigasyon | Geri kaydırma | Pencere / Sistem | Birincil |
| Manipülasyon | Sıkıştırarak yakınlaştırma | View | Hayır |
| Bağlamsal | Uzun basma | View | Mümkün |
Android SDK, düşük seviyeli MotionEvent'ten yüksek seviyeli GestureDetector ve GestureOverlayView'e kadar çok seviyeli bir hareket işleme sistemi sağlar. Doğru seviyeyi seçmek, hareketin karmaşıklığına ve performans gereksinimlerine bağlıdır.
GestureDetector, bir MotionEvent dizisini belirli hareketlere (onDown, onShowPress, onSingleTapUp, onScroll, onLongPress, onFling) dönüştüren yüksek seviyeli bir sınıftır. Geliştirici, GestureDetector.SimpleOnGestureListener'ın gerekli yöntemlerini geçersiz kılar ve tanınmış bir olay alır. GestureDetector, ölçeklendirme dışındaki tüm standart hareketler için önerilir — bunun için ScaleGestureDetector vardır.
val gestureDetector = GestureDetector(this, object : GestureDetector.SimpleOnGestureListener() {
override fun onFling(
e1: MotionEvent?, e2: MotionEvent,
velocityX: Float, velocityY: Float
): Boolean {
val deltaX = e2.x - (e1?.x ?: 0f)
return if (Math.abs(deltaX) > Math.abs(e2.y - (e1?.y ?: 0f))) {
if (deltaX > 0) onSwipeRight() else onSwipeLeft()
true
} else false
}
})
view.setOnTouchListener { _, event -> gestureDetector.onTouchEvent(event) }
TouchDelegate, bir View'in dokunma alanını genişletmek için bir mekanizmadır. Hedef öğe minimum dokunma boyutu olan 48dp'den küçük olduğunda kullanılır. Örneğin, ekranın köşesindeki küçük bir "Kapat" düğmesi, görünür boyutunu değiştirmeden vuruş alanını genişleten bir TouchDelegate alır. Google, 48x48dp'den küçük tüm etkileşimli öğeler için TouchDelegate önerir.
Compose, hareketleri işlemek için değiştiriciler sağlar: clickable, draggable, swipeable, combinedClickable (çift dokunma ve uzun basma için). Dahili olarak Compose, düşük seviyeli işleme için PointerInputScope kullanır, ancak çoğu geliştiricinin yalnızca yüksek seviyeli değiştiricilere ihtiyacı vardır. Özel hareketler için awaitPointerEvent ile pointerInput kullanın.
iOS SDK, UIGestureRecognizer mimarisini kullanır — bir UITouch dizisini analiz eden ve bilinen bir hareketle eşleşip eşleşmediğini belirleyen soyut bir temel sınıf. Apple, mümkün olan her yerde standart tanıyıcıları kullanmayı ve yalnızca benzersiz hareketler için özel alt sınıflar oluşturmayı önerir.
UIKit, kullanıma hazır tanıyıcılar seti sağlar: UITapGestureRecognizer, UISwipeGestureRecognizer, UIPanGestureRecognizer, UIPinchGestureRecognizer, UIRotationGestureRecognizer, UILongPressGestureRecognizer. Her tanıyıcının durumları vardır (possible, began, changed, ended, cancelled, failed) — geliştirici, hareketin farklı aşamalarında tepki vermek için durumu izler.
let swipeBack = UISwipeGestureRecognizer(
target: self,
action: #selector(handleSwipeBack)
)
swipeBack.direction = .right
view.addGestureRecognizer(swipeBack)
@objc func handleSwipeBack() {
navigationController?.popViewController(animated: true)
}
SwiftUI, Compose'a benzer şekilde bildirimsel hareket değiştiricileri kullanır: onTapGesture, onLongPressGesture, MagnificationGesture, RotationGesture, DragGesture. SwiftUI, simultaneousGesture, sequencedGesture ve exclusiveGesture aracılığıyla hareketler arasındaki çakışmaları otomatik olarak yönetir — aynı anda tetiklendiğinde hareket önceliğini belirleyen değiştiriciler.
Image("photo")
.gesture(
MagnificationGesture()
.onChanged { scale in
self.currentScale = scale
}
.sequenced(before: DragGesture())
)
InteractivePopGestureRecognizer, UINavigationController'da geri kaydırma hareketini kontrol eden bir sistem tanıyıcısıdır. Varsayılan olarak, kök ekran hariç tüm ekranlar için aktiftir. Uygulamanız özel bir NavigationBar kullanıyorsa, interactivePopGestureRecognizer çalışmayı durdurabilir — navigationController.interactivePopGestureRecognizer?.delegate aracılığıyla programatik olarak etkinleştirilmesi gerekir.
Hareket çatışması, hareket navigasyonundaki en zorlu sorunlardan biridir. Özel bir hareket (örneğin, sol kenardan kaydırarak Drawer açma) sistem hareketiyle (iOS veya Android'de geri kaydırma) çakıştığında, sistem hangi hareketin öncelikli olduğunu belirlemelidir. Bu çatışmayı doğru şekilde yönetmek kullanıcı deneyimi için kritiktir.
Android 10+, uygulamanın WindowInsets aracılığıyla kendi hareketleri için ekran alanları ayırmasına izin verir. Sistem hareketlerinin tetiklenmemesi gereken bölgeleri belirtmek için ViewCompat.setSystemGestureExclusionRects kullanın. Örneğin, soldaki bir Drawer için, sol ekran kenarını (200dp genişliğe kadar) sistem geri kaydırmasından hariç tutabilirsiniz. Google bir sınır belirlemiştir: her tarafta 200dp'ye kadar hariç tutulabilir.
val exclusionRect = Rect(0, 0, 200, height)
ViewCompat.setSystemGestureExclusionRects(
drawerView,
listOf(SystemGestureExclusionRect(exclusionRect))
)
iOS, UIGestureRecognizerDelegate'te gestureRecognizerShouldBegin yöntemini sağlar; bu, özel bir tanıyıcının tanımayı başlatıp başlatmayacağına karar vermesine olanak tanır. Sol kenardan Drawer kaydırması için dokunma konumunu kontrol edebilirsiniz: kullanıcı Drawer'ı sürüklüyorsa (mesafe eşiği aşıyorsa), özel hareket kontrolü alır. Hareket tanınmazsa, sistem kontrolü InteractivePopGestureRecognizer'a geri verir.
Hareket Navigasyonu, özellikle sistem hareket navigasyonuna sahip cihazlarda dikkatli tasarım gerektirir. Yaygın hatalara ve bunları düzeltmek için önerilere bakalım.
En yaygın hata, sistem hareket bölgelerine (sol ve sağ kenarlar, alt kenar) etkileşimli öğeler yerleştirmek veya özel kaydırmalar uygulamaktır. Kullanıcı bir eylem gerçekleştirmeye çalışır, ancak bunun yerine sistem navigasyonu tetiklenir. Her zaman sistem hareketleri için boşluklar sağlayın ve çakışmaları exclusion rects aracılığıyla yönetin.
Hareket parametreleri (hız eşiği, minimum mesafe) varsayılan olarak platformlar arasında farklılık gösterir. Uygulamanız çapraz platform ise, parametreleri bir platformdan diğerine kopyalamayın — her hareketi Android ve iOS'ta ayrı ayrı test edin. Flutter ve React Native bazı parametreleri otomatik olarak uyarlar, ancak hepsini değil.
Her hareket görsel geri bildirimle desteklenmelidir: renk değişimi, dönüşüm, animasyon. Kullanıcı, hareketin tanındığını ve eylemin yürütüldüğünü anlamalıdır. iOS'ta sistem tanıyıcıları otomatik olarak dokunsal geri bildirim sağlar; Android'de HapticFeedbackConstants aracılığıyla eklenmesi gerekir.
Tüm kullanıcılar hareketleri gerçekleştiremez — sınırlı motor becerilere sahip kişiler navigasyon için VoiceOver ve TalkBack kullanır. Her hareketin bir düğme alternatifi olmalıdır. Google ve Apple, tüm hareket eylemlerinin erişilebilirlik için kullanılabilir kontrollerle kopyalanmasını şart koşar.
Sıkça Sorulan Sorular
iOS — Apple, 2017'de iPhone X ile hareket navigasyonunu tanıttı ve Ana Sayfa düğmesini alt kenardan kaydırmayla değiştirdi. Android, Android 10 (2020) ile bu örneği takip ederek düğmelere alternatif olarak hareketleri sundu.
Kaydırma yüksek hızda (px/sn) hızlı bir harekettir ve kesiklidir. Scroll düşük hızda yavaş bir harekettir ve süreklidir. Ayırt etmek için velocityX/Y kullanın: eşik genellikle platforma bağlı olarak 500—1000 px/sn'dir.
Hayır — Android ve iOS, bir uygulamanın sistem hareket navigasyonunu devre dışı bırakmasına izin vermez. Yalnızca exclusion rects (Android) veya gestureRecognizerShouldBegin (iOS) aracılığıyla ekran alanları ayırabilirsiniz.
Android Emulator, Ctrl+tıklama ile çoklu dokunmayı destekler (ikinci parmak ekleme). iOS Simulator, iki parmak için Option+tıklama kullanır. Flutter test, birim testlerinde kaydırmaları simüle etmek için WidgetTester.timedDrag kullanır.
Hareket Savaşı (Gesture War), iki tanıyıcının aynı dokunuşu işlemeye çalışması durumundaki çatışmadır. Önceliklerle önleyin: iOS'ta require(toFail:), Compose'da sequentialGesture ve exclusiveGesture kullanın. Flutter, otomatik çözüm için GestureArena kullanır.
Ö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