Full Screen Cover — un stil de prezentare modală în iOS, în care noul ecran ocupă întregul afișaj fără vizibilitatea conținutului părinte. Spre deosebire de Page Sheet, Full Screen Cover ascunde complet ecranul anterior și este utilizat pentru conținut media, editori foto și ecrane de autentificare. Potrivit Apple Developer, 2025, acest stil a fost implicit până la iOS 13, dar rămâne preferat pentru scenarii imersive. În SwiftUI, modificatorul .fullScreenCover oferă o API declarativă pentru prezentarea pe ecran complet.
Puncte principale
Full Screen Cover — este un stil de prezentare modală în iOS, în care controlerul prezentat ocupă întregul ecran al dispozitivului. Conținutul părinte este complet ascuns, ceea ce creează un efect de imersiune și concentrează utilizatorul asupra sarcinii curente.
Până la iOS 13, Full Screen Cover era singurul stil de prezentare modală pe iPhone. Toate apelurile present(_:animated:completion:) utilizau implicit .fullScreen. Începând cu iOS 13, Apple a schimbat stilul implicit la .automatic, care pentru iPhone alege .pageSheet. Cu toate acestea, Full Screen Cover rămâne disponibil și este utilizat pentru scenarii unde concentrarea completă este importantă.
Spre deosebire de Page Sheet, Full Screen Cover nu permite interacțiunea cu conținutul părinte și nu îl afișează sub fereastra modală. Utilizatorul nu poate închide Full Screen Cover prin glisare în jos — pentru închidere este necesar un apel programatic dismiss(animated:completion:) sau un buton de închidere pe ecran. Acest comportament este important de luat în considerare la proiectarea UX.
Page Sheet — al doilea stil principal de prezentare modală, apărut în iOS 13. Page Sheet se afișează ca un card cu margine sus, sub care se vede ecranul părinte. Utilizatorul poate închide Page Sheet prin glisare în jos. Full Screen Cover, dimpotrivă, ascunde conținutul părinte și nu suportă închiderea prin glisare.
| Caracteristică | Full Screen Cover | Page Sheet |
|---|---|---|
| Acoperirea fundalului | Completă, conținutul părinte nu se vede | Parțială, părintele se vede sub card |
| Închidere prin glisare | Nu, doar programatic sau prin buton | Da, glisarea în jos închide |
| Utilizare tipică | Video, cameră, editor foto, PDF | Formulare, setări, vizualizare detalii |
| Animația de afișare | De jos în sus, ecran complet | De jos în sus, card cu margine |
| Disponibilitate | iOS 2+ | iOS 13+ |
Alegerea între Full Screen Cover și Page Sheet depinde de conținut și context. Se recomandă utilizarea Full Screen Cover pentru conținut care necesită atenție deplină: video în modul ecran complet, previzualizare fotografii, scanare documente. Page Sheet — pentru sarcini unde contextul ecranului părinte este important: formulare de editare, selectare opțiuni, vizualizare detalii.
UIKit oferă constanta UIModalPresentationStyle.fullScreen pentru configurarea stilului de prezentare modală. Setarea acestei proprietăți pe UIViewController înainte de apelul present garantează că controlerul se va afișa pe tot ecranul. Controlerul gestionează și comportamentul la apariția tastaturii și procesarea evenimentelor sistemice.
După setarea stilului .fullScreen, se recomandă configurarea presentationController?.delegate pentru gestionarea evenimentelor de închidere. Delegatul UIAdaptivePresentationControllerDelegate permite interceptarea încercării de închidere și prevenirea pierderii datelor. Spre deosebire de Page Sheet, pentru Full Screen Cover delegatul se activează doar la apelul programatic dismiss.
Full Screen Cover gestionează corect rotația ecranului și apariția tastaturii. La rotație, controlerul modal se adaptează automat la noua orientare. UIKeyboardWillShowNotification permite deplasarea conținutului în sus la apariția tastaturii, astfel încât câmpurile de text să rămână vizibile. Spre deosebire de Page Sheet, Full Screen Cover nu își schimbă dimensiunile la apariția tastaturii.
let playerVC = VideoPlayerViewController()
playerVC.modalPresentationStyle = .fullScreen
playerVC.modalTransitionStyle = .crossDissolve
present(playerVC, animated: true) {
playerVC.startPlayback()
}
// Respinge
dismiss(animated: true) {
print("Player respins")
}
SwiftUI oferă modificatorul .fullScreenCover pentru crearea declarativă a ferestrelor modale pe ecran complet. Spre deosebire de .sheet (Page Sheet), .fullScreenCover creează stilul .fullScreen cu comportament analog: acoperire completă a conținutului și absența închiderii prin glisare.
Modificatorul acceptă un binding de tip Bool sau un obiect identificabil opțional. La setarea binding la true, SwiftUI animează apariția ferestrei pe ecran complet. Pentru transmiterea datelor se utilizează parametrul onDismiss și o închidere cu conținut. Valoarea de mediu \.dismiss permite închiderea ferestrei modale din interior.
Alegerea între .fullScreenCover și .sheet în SwiftUI este similară cu UIKit: .fullScreenCover pentru conținut imersiv, .sheet pentru carduri. SwiftUI selectează automat comportamentul corect de închidere: .sheet poate fi închis prin glisare, .fullScreenCover — doar programatic. Modificatoarele pot fi combinate în aceeași ierarhie de View.
struct CameraView: View {
@State private var showCamera = false
var body: some View {
Button("Deschide camera") {
showCamera = true
}
.fullScreenCover(isPresented: $showCamera) {
CameraPreviewView()
.ignoresSafeArea()
}
}
}
struct CameraPreviewView: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
ZStack {
Color.black.ignoresSafeArea()
VStack {
Spacer()
Button("Captură") { dismiss() }
.foregroundColor(.white)
}
}
}
}
Full Screen Cover suportă animații personalizate prin UIModalTransitionStyle în UIKit și tranziții personalizate în SwiftUI. Stilurile standard: .coverVertical (de jos în sus), .crossDissolve (apariție treptată), .flipHorizontal (întoarcere) și .partialCurl (efect de pagină).
Pentru o animație complet personalizată, implementați protocolul UIViewControllerAnimatedTransitioning. Acesta vă permite să definiți durata animației și tranziția în sine prin metoda animateTransition(using:). Controlerul de animație este atribuit prin delegatul UINavigationControllerDelegate sau UIViewControllerTransitioningDelegate.
În SwiftUI, tranzițiile personalizate pentru .fullScreenCover se creează prin matchedGeometryEffect. Acest modificator animează mutarea unui element din View-ul părinte în fereastra pe ecran complet. De exemplu, la apăsarea unei miniaturi foto, aceasta se extinde lin pe tot ecranul, creând un efect de continuitate. MatchedGeometryEffect funcționează cu id și namespace, care leagă elementul în poziția sursă și țintă.
struct PhotoViewer: View {
@State private var selectedPhoto: String?
@Namespace private var animation
var body: some View {
HStack {
ForEach(["photo1", "photo2"], id: \.self) { photo in
Image(photo)
.matchedGeometryEffect(id: photo, in: animation)
.onTapGesture { selectedPhoto = photo }
}
}
.fullScreenCover(item: $selectedPhoto) { photo in
Image(photo)
.matchedGeometryEffect(id: photo, in: animation)
.ignoresSafeArea()
}
}
}
Full Screen Cover este recomandat pentru scenarii în care conținutul trebuie să ocupe întregul ecran fără distragerea atenției de la interfața părinte. Apple HIG evidențiază trei categorii principale: conținut media, instrumente de creare a conținutului și interfețe temporare de sistem.
Playere video, vizualizare fotografii, citire PDF și benzi desenate — exemple tipice de utilizare a Full Screen Cover. AVPlayerViewController în iOS utilizează automat modul ecran complet la trecerea în landscape. Editorii foto precum Adobe Lightroom deschid editorul pe ecran complet deasupra bibliotecii de imagini.
Cameră, scaner de documente, înregistrare audio — sarcini care necesită atenția deplină a utilizatorului. UIImagePickerController până la iOS 14 utiliza Full Screen Cover pentru cameră. Începând cu iOS 14, selectorul de sistem utilizează Page Sheet, dar dezvoltatorul poate forța .fullScreen pentru o cameră personalizată.
Nu utilizați Full Screen Cover pentru: formulare de înregistrare (preferabil Page Sheet), ecrane cu introducere text unde contextul paginii părinte este important și navigare secvențială în interiorul ferestrei modale. Material Design recomandă, de asemenea, evitarea blocării butonului de înapoi al sistemului — în iOS acest lucru este permis, dar utilizatorul trebuie să aibă o modalitate clară de închidere printr-un element de interfață.
Întrebări frecvente
.fullScreen ascunde controlerul părinte și îl elimină din ierarhia de afișare. .overFullScreen afișează controlerul modal deasupra celui părinte, dar părintele rămâne în ierarhie și continuă să primească evenimente. overFullScreen este util pentru fundaluri transparente și animații personalizate ale straturilor.
Apple a schimbat stilul implicit în iOS 13 pentru a îmbunătăți interacțiunea cu utilizatorul. Page Sheet permite vizualizarea contextului ecranului părinte și închiderea ferestrei modale prin glisare, ceea ce accelerează navigarea. Full Screen Cover rămâne pentru scenarii unde este necesară concentrarea deplină fără distragerea prin fundal.
În UIKit, apelați dismiss(animated:completion:) pe presentingViewController sau presentedViewController. În SwiftUI, utilizați valoarea de mediu \.dismiss și apelați-o ca funcție. Pentru închiderea programatică din controlerul părinte, modificați binding-ul transmis la .fullScreenCover la false.
Da, Full Screen Cover funcționează pe iPad. Pentru iPad sunt disponibile stiluri suplimentare: .formSheet (fereastră centrată de dimensiune fixă) și .currentContext (relativ la controlerul părinte). Pe iPad, Full Screen Cover poate arăta ca Page Sheet dacă modalPresentationStyle nu este setat forțat.
Spre deosebire de Page Sheet, Full Screen Cover nu se închide prin glisare, deci pierderea datelor este posibilă doar la dismiss programatic. Suprascrieți metoda dismiss(animated:completion:) sau utilizați UIAdaptivePresentationControllerDelegate care este apelat înainte de închidere. Afișați UIAlertController cu opțiunile: salvare, anulare sau rămânere pe ecran.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și