Modal Presentation у мобилном развоју: шта је то, врсте екрана

Аутор: IT Sectr Објављено: 2026-06-09 Време читања: 5 мин

Modal Presentation — начин приказивања екрана изнад тренутног контекста са блокирањем интеракције са претходним интерфејсом. У мобилном развоју, модални прозори се користе за фокусиране задатке: унос података, потврђивање радњи, ауторизација и избор опција. Према Apple HIG, 2025, модалне презентације не би требало да заузимају више од 20% навигационих сценарија у апликацији. У Android-у модалност се реализује кроз DialogFragment, BottomSheet и Activity са одређеним launch-флаговима.

Главне ствари

  • Modal Presentation — техника приказа екрана која блокира интеракцију са претходним садржајем до затварања модалног прозора.
  • iOS користи UIModalPresentationStyle са варијантама .fullScreen, .pageSheet, .formSheet и .automatic.
  • Android реализује модалност кроз DialogFragment, BottomSheetDialogFragment и Activity са Intent флаговима.
  • SwiftUI пружа модификаторе .sheet и .fullScreenCover за декларативну модалну презентацију.
  • Jetpack Compose користи Dialog и ModalBottomSheet за креирање модалних интерфејса.

Шта је Modal Presentation?

Modal Presentation — је образац навигације при којем се нови екран појављује изнад тренутног, привремено блокирајући интеракцију са родитељским садржајем. Корисник мора експлицитно да заврши модални задатак (отказивање, чување, затварање) да би се вратио у претходно стање.

Модалност решава когнитивни задатак: фокусира пажњу корисника на једну радњу без ометања остатком интерфејса. Ово је критично за формуларе за регистрацију, дијалоге за потврду, избор датотека и ауторизацију преко услуга трећих страна. Human Interface Guidelines компаније Apple препоручују коришћење модалности само за задатке који захтевају завршетак пре наставка рада.

За разлику од веб модалних прозора, мобилна Modal Presentation може бити преко целог екрана (заузима цео екран) или делимична (Page Sheet, Bottom Sheet). Избор типа зависи од контекста задатка и платформских конвенција. iOS тежи ка Page Sheet-у за већину сценарија, остављајући Full Screen за видео плејере и фото едиторе.

Push Presentation (стек навигација) додаје екран у навигациони стек и аутоматски приказује дугме за назад. Корисник се може вратити на претходни екран у било ком тренутку. Modal Presentation, напротив, подразумева експлицитан завршетак: дугме за назад или не постоји, или затвара модални прозор, а не враћа на претходни екран.

Главне разлике између модалне и push презентације: Modal Presentation блокира навигацију уназад без губитка података, захтева радњу за затварање (Save, Cancel, Done) и обично представља засебан задатак. Push Presentation чува хијерархију навигације, аутоматски додаје дугме за повратак и погодна је за секвенцијални преглед садржаја.

КарактеристикаModal PresentationPush Presentation
Блокирање назадДа, захтева експлицитну радњуНе, дугме за назад увек доступно
Типична употребаФормулари, ауторизација, изборДетаљан преглед, навигација
АнимацијаОдоздо нагоре (iOS), слајд (Android)Здесна налево (iOS)
Стек навигацијеНе додаје се у главни стекДодаје се у стек

У пракси, избор између Modal и Push зависи од контекста. Препоручује се коришћење модалности за задатке које корисник мора да заврши пре наставка, а Push — за секвенцијално истраживање садржаја. Мешање образаца на истом екрану доводи до конфузије и погоршава UX.

Модална презентација у iOS-у: UIKit и SwiftUI

iOS нуди неколико стилова модалне презентације кроз енумерацију UIModalPresentationStyle. UIKit подржава .fullScreen (пуни екран), .pageSheet (картица са размаком одозго), .formSheet (центрирани прозор на iPad-у) и .automatic (избор од стране система на основу контекста). Од iOS 13, подразумевани стил је постао .automatic, који за iPhone бира .pageSheet.

UIViewController.present

Основни метод UIKit-а за модалну презентацију — present(_:animated:completion:). Контролер који позива метод постаје presentingViewController, а нови — presentedViewController. Затварање се врши кроз dismiss(animated:completion:). SwiftUI пружа модификатор .sheet за слично понашање.

SwiftUI .sheet

Декларативни приступ SwiftUI користи модификаторе .sheet и .fullScreenCover. Први креира Page Sheet, други — модалну презентацију преко целог екрана. Оба прихватају binding на Bool или идентификовани објекат који управља видљивошћу модалног прозора. Затварање се дешава постављањем 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() }
    }
}

Модална презентација у Android-у: Fragment и Compose

Android нема јединствени API за модалну презентацију као iOS. Уместо тога, платформа нуди неколико механизама: DialogFragment за дијалог прозоре, BottomSheetDialogFragment за доње панеле и Activity са флаговима NEW_TASK и CLEAR_TOP за модалне екране. У Jetpack Compose-у се појавила јединствена компонента Dialog за све врсте модалних прозора.

DialogFragment

DialogFragment — основна класа за модалне прозоре у Android SDK-у. Управља животним циклусом дијалога, обрађује ротацију екрана и чува стање. Фрагмент се приказује изнад Activity без блокирања навигационог стека. Затварање се врши кроз dismiss() или клик изван области дијалога ако је setCancelable(true).

Modal Bottom Sheet

BottomSheetDialogFragment приказује модални прозор као панел који се подиже одоздо. Овај образац је популаран у 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("Модални формулар", style = MaterialTheme.typography.headlineSmall)
                Button(onClick = onDismiss) {
                    Text("Затвори")
                }
            }
        }
    }
}

Најбоље праксе модалне презентације

Модални прозори — моћан UX алат, али њихово прекомерно коришћење погоршава корисничко искуство. Apple HIG и Google Material Design се слажу у препорукама: модалност треба примењивати за фокусиране задатке и не прелазити 20% укупног броја навигационих радњи.

Када користити модалну презентацију

Модални прозори су погодни за сценарије: унос података (формулари за регистрацију, профил), потврда (брисање, слање), избор (бирач датума, менаџер датотека) и ауторизација (OAuth, Firebase Auth). Ако задатак траје мање од 30 секунди и захтева блокирање контекста — изаберите модалност.

Шта избегавати

Немојте користити модалну презентацију за: секвенцијални преглед садржаја (користите Push), приказивање грешака (користите Toast или Snackbar), рекламе и промо понуде без експлицитног захтева корисника. Material Design препоручује избегавање угнежђених модалних прозора — то дезоријентише корисника и нарушава хијерархију навигације.

За модалне прозоре са текстуалним пољима обавезно обрађујте губитак фокуса тастатуре. При појави тастатуре, модални прозор треба да се помери нагоре како би корисник видео текст који уноси. UIKeyboardWillShowNotification у iOS-у и adjustResize у Android-у решавају овај проблем.

Примери кода у Swift и Kotlin

Размотримо имплементацију модалне презентације на обе платформе. Пример у Swift-у показује подешавање UIModalPresentationStyle.pageSheet са делегатом за обраду затварања. Пример у 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("Модални прозор затворен")
    }
}
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 је погодан за секвенцијални преглед садржаја, где корисник може слободно да се враћа назад. Модални прозор не треба да садржи навигацију унутар себе.

Који стил модалне презентације изабрати у iOS-у?

Од iOS 13, подразумевани стил .automatic бира .pageSheet за iPhone. .pageSheet је погодан за већину сценарија (формулари, детаљи). .fullScreen — за медијски садржај (видео, фото едитори). .formSheet — за iPad апликације где је потребан центрирани прозор.

Како имплементирати модални прозор у Jetpack Compose-у?

Jetpack Compose пружа компоненту Dialog за једноставне модалне прозоре и ModalBottomSheet за доње панеле. Dialog прихвата onDismissRequest и садржај у Compose стилу. За чување стања користите rememberSaveable унутар дијалога.

Могу ли се модални прозори угнежђивати један у други?

Apple HIG и Material Design не препоручују угнежђене модалне прозоре. Ако корисник отвори модални прозор изнад другог модалног прозора, губи контекст и може се збунити у хијерархији. Уместо угнежђивања користите Step Indicator или Wizard образац са једним модалним прозором.

Како обрадити затварање модалног прозора при губитку података?

Користите UIAdaptivePresentationControllerDelegate у iOS-у (метод presentationControllerShouldDismiss) или OnBackPressedDispatcher у Android-у. У случају несачуваних података прикажите AlertDialog са опцијама: сачувај, откажи измене, остани на екрану. Ово спречава случајни губитак података од стране корисника.

Закључци

  • Modal Presentation — образац навигације који блокира интеракцију са родитељским садржајем до завршетка задатка.
  • iOS подржава .fullScreen, .pageSheet, .formSheet кроз UIModalPresentationStyle и .sheet у SwiftUI.
  • Android реализује модалност кроз DialogFragment, BottomSheet и Dialog у Jetpack Compose-у.
  • Modal се разликује од Push-а блокирањем назад и захтевом за експлицитном радњом за затварање.
  • Модални прозори не би требало да прелазе 20% навигационих сценарија и не би требало да буду угнежђени.
  • Губитак података при затварању модалног прозора треба спречавати кроз делегате и дијалоге за потврду.
  • Препоручује се избор Page Sheet-а у iOS-у и DialogFragment-а у Android-у за стандардне модалне задатке.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође