Modal Presentation در توسعه موبایل: چیست، انواع صفحه‌ها

نویسنده: IT Sectr منتشر شده: 2026-06-09 زمان مطالعه: 5 دقیقه

Modal Presentation — روشی برای نمایش صفحه روی زمینه فعلی با مسدود کردن تعامل با رابط قبلی. در توسعه موبایل از پنجره‌های Modal برای کارهای متمرکز استفاده می‌شود: ورود داده، تأیید اقدامات، احراز هویت و انتخاب گزینه‌ها. بر اساس Apple HIG, 2025، ارائه‌های Modal نباید بیش از 20% سناریوهای ناوبری در برنامه را تشکیل دهند. در Android Modal از طریق DialogFragment، BottomSheet و Activity با پرچم‌های launch مشخص پیاده‌سازی می‌شود.

نکات اصلی

  • Modal Presentation — تکنیک نمایش صفحه که تعامل با محتوای قبلی را تا بسته شدن پنجره Modal مسدود می‌کند.
  • iOS از UIModalPresentationStyle با گزینه‌های .fullScreen، .pageSheet، .formSheet و .automatic استفاده می‌کند.
  • Android Modal را از طریق DialogFragment، BottomSheetDialogFragment و Activity با پرچم‌های Intent پیاده‌سازی می‌کند.
  • SwiftUI اصلاح‌کننده‌های .sheet و .fullScreenCover را برای ارائه اعلانی Modal فراهم می‌کند.
  • Jetpack Compose از Dialog و ModalBottomSheet برای ایجاد رابط‌های Modal استفاده می‌کند.

Modal Presentation چیست؟

Modal Presentation — الگویی از ناوبری است که در آن صفحه جدید روی صفحه فعلی ظاهر می‌شود و به طور موقت تعامل با محتوای والد را مسدود می‌کند. کاربر باید صریحاً کار Modal را تمام کند (لغو، ذخیره، بستن) تا به حالت قبلی بازگردد.

Modal بودن یک مسئله شناختی را حل می‌کند: توجه کاربر را روی یک عمل متمرکز می‌کند بدون اینکه توسط بقیه رابط پرت شود. این برای فرم‌های ثبت نام، دیالوگ‌های تأیید، انتخاب فایل و احراز هویت از طریق سرویس‌های شخص ثالث حیاتی است. Human Interface Guidelines اپل توصیه می‌کند Modal را فقط برای کارهایی استفاده کنید که برای ادامه کار نیاز به تکمیل دارند.

برخلاف پنجره‌های Modal وب، Modal Presentation موبایل می‌تواند تمام صفحه (کل صفحه را اشغال کند) یا جزئی (Page Sheet، Bottom Sheet) باشد. انتخاب نوع به زمینه کار و قراردادهای پلتفرم بستگی دارد. iOS برای بیشتر سناریوها به Page Sheet تمایل دارد و Full Screen را برای پخش‌کننده‌های ویدیو و ویرایشگرهای عکس نگه می‌دارد.

Push Presentation (ناوبری پشته‌ای) صفحه را به پشته ناوبری اضافه می‌کند و به طور خودکار دکمه بازگشت را نشان می‌دهد. کاربر می‌تواند در هر لحظه به صفحه قبلی بازگردد. Modal Presentation، برعکس، نیاز به پایان صریح دارد: دکمه بازگشت یا وجود ندارد یا پنجره Modal را می‌بندد، نه اینکه به صفحه قبلی بازگردد.

تفاوت‌های اصلی بین ارائه Modal و Push: Modal Presentation ناوبری به عقب را بدون از دست دادن داده مسدود می‌کند، برای بسته شدن نیاز به عمل دارد (Save، Cancel، Done) و معمولاً یک کار جداگانه را نشان می‌دهد. Push Presentation سلسله مراتب ناوبری را حفظ می‌کند، به طور خودکار دکمه بازگشت را اضافه می‌کند و برای مشاهده متوالی محتوا مناسب است.

ویژگیModal PresentationPush Presentation
مسدود کردن بازگشتبله، نیاز به عمل صریح داردخیر، دکمه بازگشت همیشه در دسترس است
استفاده معمولفرم‌ها، احراز هویت، انتخابمشاهده جزئیات، ناوبری
انیمیشناز پایین به بالا (iOS)، اسلاید (Android)از راست به چپ (iOS)
پشته ناوبریبه پشته اصلی اضافه نمی‌شودبه پشته اضافه می‌شود

در عمل، انتخاب بین Modal و Push به زمینه بستگی دارد. توصیه می‌شود از Modal برای کارهایی استفاده کنید که کاربر باید قبل از ادامه تکمیل کند، و از Push برای بررسی متوالی محتوا. ترکیب الگوها در یک صفحه باعث سردرگمی می‌شود و UX را بدتر می‌کند.

ارائه Modal در iOS: UIKit و SwiftUI

iOS چندین سبک ارائه Modal را از طریق enum UIModalPresentationStyle ارائه می‌دهد. UIKit از .fullScreen (تمام صفحه)، .pageSheet (کارت با فاصله از بالا)، .formSheet (پنجره متمرکز در iPad) و .automatic (انتخاب توسط سیستم بر اساس زمینه) پشتیبانی می‌کند. از iOS 13، سبک پیش‌فرض .automatic شده است که برای iPhone .pageSheet را انتخاب می‌کند.

UIViewController.present

روش پایه UIKit برای ارائه Modal — present(_:animated:completion:). کنترل‌کننده‌ای که متد را فراخوانی می‌کند presentingViewController می‌شود و کنترل‌کننده جدید presentedViewController می‌شود. بسته شدن از طریق dismiss(animated:completion:) انجام می‌شود. SwiftUI اصلاح‌کننده .sheet را برای رفتار مشابه فراهم می‌کند.

SwiftUI .sheet

رویکرد اعلانی SwiftUI از اصلاح‌کننده‌های .sheet و .fullScreenCover استفاده می‌کند. اولی Page Sheet ایجاد می‌کند، دومی — ارائه Modal تمام صفحه. هر دو یک binding به Bool یا یک شیء قابل شناسایی می‌پذیرند که visibility پنجره Modal را کنترل می‌کند. بسته شدن با تنظیم binding به false یا فراخوانی dismiss از environment انجام می‌شود.

swift
struct ContentView: View {
    @State private var showModal = false

    var body: some View {
        Button("باز کردن فرم") {
            showModal = true
        }
        .sheet(isPresented: $showModal) {
            RegistrationForm()
        }
    }
}

struct RegistrationForm: View {
    @Environment(\.dismiss) private var dismiss

    var body: some View {
        Button("ذخیره") { dismiss() }
    }
}

ارائه Modal در Android: Fragment و Compose

Android مانند iOS یک API واحد برای ارائه Modal ندارد. در عوض، پلتفرم چندین مکانیسم ارائه می‌دهد: DialogFragment برای پنجره‌های دیالوگ، BottomSheetDialogFragment برای پنل‌های پایین و Activity با پرچم‌های NEW_TASK و CLEAR_TOP برای صفحات Modal. در Jetpack Compose یک کامپوننت واحد Dialog برای همه انواع پنجره‌های Modal ظاهر شده است.

DialogFragment

DialogFragment — کلاس پایه برای پنجره‌های Modal در Android SDK. این کلاس چرخه زندگی دیالوگ را مدیریت می‌کند، چرخش صفحه را پردازش می‌کند و وضعیت را ذخیره می‌کند. Fragment بدون مسدود کردن پشته ناوبری روی Activity نمایش داده می‌شود. بسته شدن از طریق dismiss() یا کلیک خارج از ناحیه دیالوگ در صورتی که setCancelable(true) باشد انجام می‌شود.

Modal Bottom Sheet

BottomSheetDialogFragment پنجره Modal را به صورت پنلی که از پایین بالا می‌آید نمایش می‌دهد. این الگو در Material Design برای انتخاب گزینه‌ها، اشتراک‌گذاری و اقدامات سریع محبوب است. BottomSheet می‌تواند ارتفاع ثابت یا قابل گسترش (peek height + full height) داشته باشد. در Compose از ModalBottomSheet از کتابخانه Material3 استفاده می‌شود.

kotlin
@Composable
fun ModalScreen(onDismiss: () -> Unit) {
    Dialog(onDismissRequest = onDismiss) {
        Card(
            modifier = Modifier.padding(16.dp)
        ) {
            Column {
                Text("فرم Modal", style = MaterialTheme.typography.headlineSmall)
                Button(onClick = onDismiss) {
                    Text("بستن")
                }
            }
        }
    }
}

بهترین روش‌های ارائه Modal

پنجره‌های Modal — ابزار قدرتمند UX، اما استفاده بیش از حد از آنها تجربه کاربری را بدتر می‌کند. Apple HIG و Google Material Design در توصیه‌ها هم‌نظر هستند: Modal باید برای کارهای متمرکز استفاده شود و از 20% کل اقدامات ناوبری تجاوز نکند.

چه زمانی از ارائه Modal استفاده کنیم

پنجره‌های Modal برای سناریوهای زیر مناسب هستند: ورود داده (فرم‌های ثبت نام، پروفایل)، تأیید (حذف، ارسال)، انتخاب (انتخاب‌گر تاریخ، مدیر فایل) و احراز هویت (OAuth، Firebase Auth). اگر کار کمتر از 30 ثانیه طول می‌کشد و نیاز به مسدود کردن زمینه دارد — Modal را انتخاب کنید.

چه چیزی را اجتناب کنیم

از ارائه Modal استفاده نکنید برای: مشاهده متوالی محتوا (از Push استفاده کنید)، نمایش خطاها (از Toast یا Snackbar استفاده کنید)، تبلیغات و پیشنهادات تبلیغاتی بدون درخواست صریح کاربر. Material Design توصیه می‌کند از پنجره‌های Modal تو در تو خودداری کنید — این کاربر را سردرگم می‌کند و سلسله مراتب ناوبری را نقض می‌کند.

برای پنجره‌های Modal با فیلدهای متنی، حتماً از دست رفتن focus صفحه کلید را مدیریت کنید. هنگام ظاهر شدن صفحه کلید، پنجره Modal باید به بالا حرکت کند تا کاربر متن وارد شده را ببیند. UIKeyboardWillShowNotification در iOS و adjustResize در Android این مشکل را حل می‌کنند.

نمونه کد در Swift و Kotlin

بیایید پیاده‌سازی ارائه Modal را در هر دو پلتفرم بررسی کنیم. نمونه Swift تنظیم UIModalPresentationStyle.pageSheet با delegate برای مدیریت بسته شدن را نشان می‌دهد. نمونه Kotlin DialogFragment با layout سفارشی و ذخیره وضعیت را نشان می‌دهد.

swift
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 بسته شد")
    }
}
kotlin
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()
        }
    }
}

سوالات متداول

چه زمانی باید از Modal Presentation به جای Push استفاده کرد؟

از Modal Presentation برای کارهای متمرکزی استفاده کنید که کاربر باید قبل از ادامه تکمیل کند: فرم‌ها، تأییدها، احراز هویت. Push برای مشاهده متوالی محتوا مناسب است، جایی که کاربر می‌تواند آزادانه به عقب بازگردد. پنجره Modal نباید داخل خود ناوبری داشته باشد.

کدام سبک ارائه Modal را در iOS انتخاب کنیم؟

از iOS 13، سبک پیش‌فرض .automatic برای iPhone .pageSheet را انتخاب می‌کند. .pageSheet برای بیشتر سناریوها مناسب است (فرم‌ها، جزئیات). .fullScreen — برای محتوای چندرسانه‌ای (ویدئو، ویرایشگرهای عکس). .formSheet — برای برنامه‌های iPad که نیاز به پنجره متمرکز دارند.

چگونه یک پنجره Modal در Jetpack Compose پیاده‌سازی کنیم؟

Jetpack Compose کامپوننت Dialog را برای پنجره‌های Modal ساده و ModalBottomSheet را برای پنل‌های پایین فراهم می‌کند. Dialog onDismissRequest و محتوا به سبک Compose را می‌پذیرد. برای ذخیره وضعیت از rememberSaveable داخل دیالوگ استفاده کنید.

آیا می‌توان پنجره‌های Modal را در یکدیگر تو در تو قرار داد؟

Apple HIG و Material Design پنجره‌های Modal تو در تو را توصیه نمی‌کنند. اگر کاربر یک پنجره Modal را روی پنجره Modal دیگر باز کند، زمینه را از دست می‌دهد و ممکن است در سلسله مراتب سردرگم شود. به جای تو در تو کردن از Step Indicator یا الگوی Wizard با یک پنجره Modal استفاده کنید.

چگونه بسته شدن پنجره Modal را هنگام از دست دادن داده مدیریت کنیم؟

از UIAdaptivePresentationControllerDelegate در iOS (متد presentationControllerShouldDismiss) یا OnBackPressedDispatcher در Android استفاده کنید. در صورت وجود داده‌های ذخیره نشده، AlertDialog با گزینه‌های: ذخیره، لغو تغییرات، ماندن در صفحه نمایش دهید. این کار از از دست دادن تصادفی داده توسط کاربر جلوگیری می‌کند.

خلاصه

  • Modal Presentation — الگوی ناوبری که تعامل با محتوای والد را تا تکمیل کار مسدود می‌کند.
  • iOS از .fullScreen، .pageSheet، .formSheet از طریق UIModalPresentationStyle و .sheet در SwiftUI پشتیبانی می‌کند.
  • Android Modal را از طریق DialogFragment، BottomSheet و Dialog در Jetpack Compose پیاده‌سازی می‌کند.
  • Modal با Push از طریق مسدود کردن بازگشت و نیاز به عمل صریح برای بسته شدن تفاوت دارد.
  • پنجره‌های Modal نباید از 20% سناریوهای ناوبری تجاوز کنند و نباید تو در تو باشند.
  • از دست دادن داده هنگام بستن پنجره Modal باید از طریق delegateها و دیالوگ‌های تأیید جلوگیری شود.
  • توصیه می‌شود برای کارهای Modal استاندارد Page Sheet در iOS و DialogFragment در Android انتخاب شود.

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

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

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

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