Modal Sunum, mevcut bağlamın üzerinde bir ekran görüntüleme ve önceki arayüzle etkileşimi engelleme yöntemidir. Mobil geliştirmede, modal pencereler odaklanmış görevler için kullanılır: veri girişi, eylem onayı, yetkilendirme ve seçenek seçimi. Apple HIG, 2025'ye göre, modal sunumlar bir uygulamadaki navigasyon senaryolarının %20'sinden fazlasını oluşturmamalıdır. Android'de modalite, DialogFragment, BottomSheet ve belirli başlatma bayraklarına sahip Activity aracılığıyla uygulanır.
Önemli Noktalar
Modal Sunum, yeni bir ekranın mevcut ekranın üstünde belirerek üst içerikle etkileşimi geçici olarak engellediği bir navigasyon desenidir. Kullanıcı, önceki duruma dönmek için modal görevi (iptal et, kaydet, kapat) açıkça tamamlamalıdır.
Modalite bilişsel bir görevi çözer: kullanıcının dikkatini arayüzün geri kalanından uzaklaştırmadan tek bir eyleme odaklar. Bu, kayıt formları, onay diyalogları, dosya seçimi ve üçüncü taraf hizmetler aracılığıyla yetkilendirme için kritik öneme sahiptir. Apple'ın Human Interface Guidelines’ı, modalitenin yalnızca devam etmeden önce tamamlanması gereken görevler için kullanılmasını önerir.
Web modal pencerelerinin aksine, mobil Modal Sunum tam ekran (tüm ekranı kaplayan) veya kısmi (Page Sheet, Bottom Sheet) olabilir. Tür seçimi, görev bağlamına ve platform kurallarına bağlıdır. iOS, çoğu senaryo için Page Sheet'e yönelir ve Full Screen'i video oynatıcılar ve fotoğraf düzenleyiciler için bırakır.
Push Sunumu (yığın navigasyonu), navigasyon yığına bir ekran ekler ve otomatik olarak bir geri dönme düğmesi gösterir. Kullanıcı istediği zaman önceki ekrana dönebilir. Modal Sunum ise açık bir tamamlama gerektirir: geri dönme düğmesi ya yoktur ya da önceki ekrana dönmek yerine modal pencereyi kapatır.
Modal ve push sunumu arasındaki temel farklar: Modal Sunum veri kaybı olmadan geriye dönük navigasyonu engeller, kapatmak için bir eylem gerektirir (Save, Cancel, Done) ve genellikle ayrı bir görevi temsil eder. Push Sunumu navigasyon hiyerarşisini korur, otomatik olarak bir geri dönme düğmesi ekler ve sıralı içerik görüntüleme için uygundur.
| Özellik | Modal Sunum | Push Sunumu |
|---|---|---|
| Geri engelleme | Evet, açık eylem gerektirir | Hayır, geri düğmesi her zaman mevcut |
| Tipik kullanım | Formlar, yetkilendirme, seçim | Detay görünümü, navigasyon |
| Animasyon | Aşağıdan yukarıya (iOS), kaydırma (Android) | Sağdan sola (iOS) |
| Navigasyon yığını | Ana yığına eklenmez | Yığına eklenir |
Pratikte, Modal ve Push arasındaki seçim bağlama bağlıdır. Kullanıcının devam etmeden önce tamamlaması gereken görevler için modalite kullanılması ve sıralı içerik keşfi için Push kullanılması önerilir. Aynı ekranda desenleri karıştırmak kafa karışıklığına yol açar ve kullanıcı deneyimini düşürür.
iOS, UIModalPresentationStyle numaralandırması aracılığıyla birkaç modal sunum stili sunar. UIKit, .fullScreen (tam ekran), .pageSheet (üst kenar boşluklu kart), .formSheet (iPad'de ortalanmış pencere) ve .automatic (sistem bağlama göre seçer) destekler. iOS 13'ten itibaren varsayılan stil, iPhone için .pageSheet'i seçen .automatic olmuştur.
Modal sunum için temel UIKit yöntemi present(_:animated:completion:) şeklindedir. Yöntemi çağıran denetleyici presentingViewController olur ve yenisi presentedViewController olur. Kapatma, dismiss(animated:completion:) aracılığıyla yapılır. SwiftUI, benzer davranış için .sheet değiştiricisini sağlar.
SwiftUI'nin bildirimsel yaklaşımı, .sheet ve .fullScreenCover değiştiricilerini kullanır. İlki Page Sheet oluşturur, ikincisi tam ekran modal sunum oluşturur. Her ikisi de modal pencerenin görünürlüğünü kontrol eden bir Bool veya tanımlanabilir bir nesneye bağlama kabul eder. Kapatma, bağlama false olarak ayarlandığında veya ortamdan dismiss çağrıldığında gerçekleşir.
struct ContentView: View {
@State private var showModal = false
var body: some View {
Button("Formu aç") {
showModal = true
}
.sheet(isPresented: $showModal) {
RegistrationForm()
}
}
}
struct RegistrationForm: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
Button("Kaydet") { dismiss() }
}
}
Android, iOS gibi modal sunum için tek bir API'ye sahip değildir. Bunun yerine platform birkaç mekanizma sunar: diyalog pencereleri için DialogFragment, alt paneller için BottomSheetDialogFragment ve modal ekranlar için NEW_TASK ve CLEAR_TOP bayraklarına sahip Activity. Jetpack Compose, tüm modal pencere türleri için birleşik bir Dialog bileşeni sunmuştur.
DialogFragment, Android SDK'daki modal pencereler için temel sınıftır. Diyalogun yaşam döngüsünü yönetir, ekran döndürmeyi işler ve durumu kaydeder. Parça, navigasyon yığını engellemeden Activity'nin üstünde görüntülenir. Kapatma, dismiss() aracılığıyla veya setCancelable(true) ise diyalog alanının dışına dokunarak yapılır.
BottomSheetDialogFragment, modal pencereyi alttan yükselen bir panel olarak görüntüler. Bu desen, Material Design'da seçenek seçimi, paylaşım ve hızlı eylemler için popülerdir. BottomSheet, sabit yükseklikte veya genişletilebilir (bakış yüksekliği + tam yükseklik) olabilir. Compose'da, Material3 kütüphanesinden ModalBottomSheet kullanılır.
@Composable
fun ModalScreen(onDismiss: () -> Unit) {
Dialog(onDismissRequest = onDismiss) {
Card(
modifier = Modifier.padding(16.dp)
) {
Column {
Text("Modal form", style = MaterialTheme.typography.headlineSmall)
Button(onClick = onDismiss) {
Text("Kapat")
}
}
}
}
}
Modal pencereler güçlü bir UX aracıdır, ancak aşırı kullanımları kullanıcı deneyimini düşürür. Apple HIG ve Google Material Design önerilerde hemfikirdir: modalite odaklanmış görevler için kullanılmalı ve tüm navigasyon eylemlerinin %20'sini geçmemelidir.
Modal pencereler şu senaryolar için uygundur: veri girişi (kayıt formları, profiller), onay (silme, gönderme), seçim (tarih seçici, dosya yöneticisi) ve yetkilendirme (OAuth, Firebase Auth). Görev 30 saniyeden az sürüyorsa ve bağlam engelleme gerektiriyorsa, modaliteyi seçin.
Modal sunumu şunlar için kullanmayın: sıralı içerik görüntüleme (Push kullanın), hata görüntüleme (Toast veya Snackbar kullanın), kullanıcının açık talebi olmadan reklamlar ve promosyon teklifleri. Material Design, iç içe modal pencerelerden kaçınılmasını önerir — bu, kullanıcının yönünü şaşırtır ve navigasyon hiyerarşisini bozar.
Metin alanları olan modal pencereler için, klavye odağı kaybını ele aldığınızdan emin olun. Klavye göründüğünde, modal pencere yukarı kaymalıdır, böylece kullanıcı girdiği metni görebilir. iOS'ta UIKeyboardWillShowNotification ve Android'de adjustResize bu görevi çözer.
Her iki platformda modal sunum uygulamasına bakalım. Swift örneği, kapatmayı işlemek için bir temsilci ile UIModalPresentationStyle.pageSheet yapılandırmasını gösterir. Kotlin örneği, özel düzen ve durum koruma ile DialogFragment'ı gösterir.
let modalVC = ModalViewController()
modalVC.modalPresentationStyle = .pageSheet
if let sheet = modalVC.sheetPresentationController {
sheet.detents = [.medium(), .large()]
sheet.prefersGrabberVisible = true
}
modalVC.presentationController?.delegate = self
present(modalVC, animated: true)
// MARK: - UIAdaptivePresentationControllerDelegate
extension ViewController: UIAdaptivePresentationControllerDelegate {
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
print("Modal kapatıldı")
}
}
class ModalDialogFragment : DialogFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_modal, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
view.findViewById<Button>(R.id.closeButton).setOnClickListener {
dismiss()
}
}
}
Sıkça Sorulan Sorular
Kullanıcının devam etmeden önce tamamlaması gereken odaklanmış görevler (formlar, onaylar, yetkilendirme) için Modal Sunum'u kullanın. Push, kullanıcının serbestçe geri dönebileceği sıralı içerik görüntüleme için uygundur. Modal bir pencere içinde navigasyon bulunmamalıdır.
iOS 13'ten itibaren varsayılan .automatic stili, iPhone için .pageSheet'i seçer. .pageSheet çoğu senaryo için uygundur (formlar, detaylar). .fullScreen medya içeriği içindir (video, fotoğraf düzenleyiciler). .formSheet, ortalanmış bir pencereye ihtiyaç duyan iPad uygulamaları içindir.
Jetpack Compose, basit modal pencereler için Dialog bileşenini ve alt paneller için ModalBottomSheet'i sağlar. Dialog, onDismissRequest ve Compose tarzında içerik kabul eder. Durumu korumak için diyalog içinde rememberSaveable kullanın.
Apple HIG ve Material Design, iç içe modal pencereleri önermez. Bir kullanıcı başka bir modal pencerenin üstünde bir modal pencere açarsa, bağlamı kaybeder ve hiyerarşi konusunda kafa karışıklığı yaşayabilir. İç içe yerleştirme yerine, tek bir modal pencereyle Adım Göstergesi veya Sihirbaz deseni kullanın.
iOS'ta UIAdaptivePresentationControllerDelegate (presentationControllerShouldDismiss yöntemi) veya Android'de OnBackPressedDispatcher kullanın. Kaydedilmemiş değişiklikler olduğunda, seçeneklerle (kaydet, değişiklikleri at, ekranda kal) bir AlertDialog gösterin. Bu, kullanıcı tarafından yanlışlıkla veri kaybını önler.
Ö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