Zmiana rozmiaru okna na iPadzie w iOS 27: obejście ma swoją cenę
Informacje o wydaniu iOS 27 od Apple podają jednozdaniowe obejście dla aplikacji na iPada, które nie obsługują ciągłej zmiany rozmiaru: należy zadeklarować obsługę wszystkich czterech orientacji interfejsu w pliku Info.plist.1 Nota pomija jednak to, że system przecina tę deklarację obowiązującą dla całej aplikacji z orientacjami obsługiwanymi przez każdy view controller.2 Poszerzenie zestawu na poziomie aplikacji poszerza go wszędzie, także na iPhonie, chyba że każdy ograniczony view controller nadpisuje supportedInterfaceOrientations.
Aktualizacja z 24 sierpnia: blokada została zdjęta. Aktualne informacje o wydaniu wskazują problem 166422120 jako naprawiony – zniknął z listy znanych problemów pomiędzy edycją bety 4 a edycją bety 6, a edycja bety 7 to potwierdza: zadeklarowane orientacje nie warunkują już ciągłej zmiany rozmiaru, zgodnie z deklarowanym zamiarem cytowanym poniżej.1 Jeśli obejście z czterema orientacjami trafiło już do wydanej aplikacji, na obecnych betach nie jest ono potrzebne; przed jego usunięciem warto ponownie sprawdzić te view controllery, którym przy okazji dodano nadpisania
supportedInterfaceOrientations, ponieważ te nadpisania nadal pełnią samodzielną funkcję nośną (opisane w tym wpisie zachowanie przecięcia zbiorów pozostaje bez zmian). Znane problemy ze zmianą rozmiaru przyUIRequiresFullScreenz okresu bety 4 również figurują jako naprawione wśród problemów rozwiązanych. Poniższa analiza jest zachowana w pierwotnym brzmieniu, zakotwiczona w becie 4, ponieważ mechanika efektów ubocznych tego obejścia nadal obowiązuje wszędzie tam, gdzie obejście pozostaje w wydanych kompilacjach. Szerszy obraz, w który wpisuje się ta zmiana, opisuje wpis Era iPhone’a o zmiennym rozmiarze.
Skrótowa wersja tej zmiany również błędnie opisuje stan bieżący. Zamiarem Apple jest to, aby zadeklarowane orientacje przestały warunkować ciągłą zmianę rozmiaru. Nota, która ten zamiar utrwala, trafiła do znanych problemów, ponieważ w becie 4 orientacje wciąż go warunkują.1
Obie połowy mają znaczenie. Zachowanie jest błędem na drodze do celowej zmiany, a obejście tego błędu ma efekt uboczny, którego nikt nie dokumentuje w tym samym miejscu.
TL;DR
W iOS i iPadOS 27 beta 4 aplikacja na iPada zbudowana z SDK iOS 27, której UISupportedInterfaceOrientations pomija którąkolwiek z czterech orientacji, jest traktowana jako niepodlegająca ciągłej zmianie rozmiaru — Apple wymienia to jako znany problem obok stwierdzenia, że orientacje „nie powinny już być warunkiem ciągłej zmiany rozmiaru”.1 Udokumentowane obejście polega na zadeklarowaniu wszystkich czterech. Poszerza to zestaw orientacji w całej aplikacji, a system ustala rotację, porównując orientacje aplikacji z orientacjami każdego view controllera.2 Kolejne cztery znane problemy dotyczą UIRequiresFullScreen, które dostarcza ciągłe aktualizacje rozmiaru tam, gdzie przewidziano dyskretne zmiany UIScreen.1 Ani UIRequiresFullScreen, ani UISupportedInterfaceOrientations nie są wycofane.34
Co naprawdę mówią informacje o wydaniu
Sprawy tej dotyczy sześć wpisów z sekcji UIKit w informacjach o wydaniu iOS i iPadOS 27 beta 4, z czego pięć pozostaje otwartych.1
Sama blokada, wpisana wśród znanych problemów:
„Na iPadzie, jeśli aplikacja na iPada jest zbudowana z SDK iOS 27, a jej
UISupportedInterfaceOrientationsnie zawiera wszystkich czterech orientacji interfejsu, aplikacja jest traktowana jako niepodlegająca ciągłej zmianie rozmiaru. Począwszy od iOS 27, obsługiwane orientacje interfejsu nie powinny już być warunkiem ciągłej zmiany rozmiaru.”
Warto zwrócić uwagę na tryb drugiego zdania. „Nie powinny już być warunkiem” opisuje zachowanie zamierzone. Wpis istnieje jako znany problem, ponieważ zachowanie w wydanym systemie jeszcze nie odpowiada temu zamiarowi.
Ta różnica zmienia sposób działania. Gdyby orientacje faktycznie przestały warunkować zmianę rozmiaru, radą byłoby usunięcie obejść. Ponieważ nadal ją warunkują, radą jest zastosowanie obejścia i przygotowanie się na to, że jego powód zniknie.
Cztery znane problemy wokół UIRequiresFullScreen:
Aplikacja na iPada zbudowana z SDK iOS 27, która ustawia UIRequiresFullScreen, otrzymuje ciągłe aktualizacje rozmiaru, podczas gdy „każda zmiana rozmiaru powinna być zamiast tego dostarczana jako dyskretna zmiana na nowy UIScreen ze zaktualizowanymi bounds”. To samo dotyczy aplikacji przeznaczonej wyłącznie na iPhone’a uruchomionej na iPadzie, a także sytuacji w iPhone Mirroring.1
Czwarty wpis obejmuje obsługę orientacji w iPhone Mirroring: aplikacja zbudowana z SDK iOS 27 otrzymuje scenę obsługującą wszystkie orientacje „niezależnie od orientacji zadeklarowanych w UISupportedInterfaceOrientations czy zwracanych przez UIViewController.supportedInterfaceOrientations”, podczas gdy te „powinny być respektowane do momentu, w którym użytkownik zacznie zmieniać rozmiar okna”.1
Jeden rozwiązany: wcześniejszy problem, w którym bounds UIScreen.main zmieniały się przy zmianie rozmiaru pod UIRequiresFullScreen, figuruje teraz wśród problemów rozwiązanych.1 W poprzedniej becie był to aktywny znany problem. Przy pracy na notatkach sprzed kilku tygodni warto sprawdzić właśnie ten wpis, zanim się go powtórzy.
Co daje ciągła zmiana rozmiaru
Zanim zważy się koszty, warto precyzyjnie określić, co właściwie zostało zablokowane, ponieważ „podlegający ciągłej zmianie rozmiaru” znaczy coś konkretnego.
Okno na iPadzie może zmieniać rozmiar na dwa sposoby. Może przeskakiwać między dyskretnymi stanami — to otrzymuje aplikacja w trybie zgodności: system, słowami Apple, „utrzymuje spójny rozmiar sceny aplikacji, ale nie prezentuje jej sceny na pełnym ekranie”.3 Albo może podążać za przeciąganiem, otrzymując strumień pośrednich rozmiarów w miarę przesuwania uchwytu zmiany rozmiaru przez użytkownika.
Różnicę widać w dłoni użytkownika. Aplikacja podlegająca ciągłej zmianie rozmiaru przebudowuje układ w trakcie ruchu okna. Aplikacja, która jej nie obsługuje, trzyma swój układ i dopasowuje go skokowo na końcu, co obok aplikacji systemowych sprawia wrażenie ociężałości.
Apple od lat zawęża ścieżkę zgodności. UIRequiresFullScreen pojawiło się w iOS 9, aby całkowicie zrezygnować z wielozadaniowości na iPadzie i z dynamicznej zmiany rozmiaru.3 Stage Manager w iPadOS 16 oraz tryb Windowed Apps w iPadOS 26 rozszerzyły możliwości okna, a dokumentacja opisuje dziś tryb zgodności raczej przez to, czego on odmawia, niż przez to, co daje.
Pytanie, na które odpowiada obejście, brzmi zatem: czy aplikacja na iPada uczestniczy w nowoczesnym zarządzaniu oknami, czy pozostaje w trybie, który Apple stale ogranicza. To warte jest zmiany w Info.plist. Nie jest warte zmiany bez zabezpieczeń — o czym mówi kolejna sekcja.
Cena obejścia
Obejście Apple mieści się w jednym zdaniu: zadeklarować wszystkie cztery orientacje interfejsu w Info.plist.1 Konsekwencja opisana jest na innej stronie.
UIViewController.supportedInterfaceOrientations dokumentuje sposób podejmowania decyzji o rotacji:2
„Aby ustalić, czy dokonać rotacji, system porównuje orientacje obsługiwane przez view controller z orientacjami obsługiwanymi przez aplikację — ustalonymi na podstawie pliku
Info.plistalbo [metody] app delegate — oraz z orientacjami obsługiwanymi przez urządzenie.”
Trzy zbiory, przecięte. Deklaracja w Info.plist jest sufitem, a nie instrukcją. Aplikacja, która pozostawała wyłącznie w orientacji pionowej dzięki wypisaniu jednej orientacji w Info.plist i nigdy niczego nie nadpisywała na poziomie view controllera, traci swoje ograniczenie w chwili zastosowania obejścia.
W aplikacji uniwersalnej odbija się to zarówno na iPhonie, jak i na iPadzie. Co więcej, własne wytyczne Apple przemawiają przeciwko szerokiej deklaracji po stronie iPhone’a: w kwestii orientacji odwróconej „najlepszą praktyką jest włączenie jej dla idiomu iPada. Urządzenia iOS bez przycisku Home, takie jak iPhone 12, nie obsługują tej orientacji. Dla idiomu iPhone’a należy wyłączyć ją całkowicie.”2 Dokumentacja Info.plist mówi to samo z drugiej strony, zaznaczając, że system ignoruje orientację odwróconą „na urządzeniach bez przycisku Home”.4
Uczciwa instrukcja składa się więc z dwóch kroków, a nie z jednego:
<!-- Info.plist: the ceiling. Required for continuous resizability on iPad. -->
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
// And the floor, on every controller that must stay constrained.
final class CaptureViewController: UIViewController {
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
UIDevice.current.userInterfaceIdiom == .pad ? .all : .portrait
}
}
Pominięcie drugiego kroku oznacza polecenie, by aplikacja uniwersalna obracała się do góry nogami na iPhonie tylko po to, by uzyskać zachowanie okien na iPadzie. Skutkiem nie jest awaria ani błąd kompilacji. Skutkiem jest widok aparatu, który obraca się w trakcie używania.
Warto też pamiętać, że domyślne wartości supportedInterfaceOrientations różnią się w zależności od idiomu, a system sięga po nie tylko wtedy, gdy shouldAutorotate zwraca true.2 Jeśli ta metoda została nadpisana, warto ponownie przeczytać opis tej zależności, zanim uzna się, że ograniczenie nadal działa.
Jak sprawdzić, czy problem dotyczy danej aplikacji
Nic z tego nie powoduje błędu kompilacji, więc audyt trzeba przeprowadzić ręcznie. Trzy kontrole, uszeregowane malejąco według oszczędzanego czasu.
Należy sprawdzić, co naprawdę deklaruje Info.plist w każdym targecie. Klucze orientacji bywają ustawiane raz, przy tworzeniu projektu, i nigdy później nieweryfikowane, a aplikacja uniwersalna może nieść inne deklaracje dla iPhone’a i dla iPada poprzez UISupportedInterfaceOrientations~ipad. Trzeba przeczytać obie.
# Every orientation and fullscreen declaration across the project
rg -l 'UISupportedInterfaceOrientations|UIRequiresFullScreen' --glob '*.plist'
# And what each one says
/usr/libexec/PlistBuddy -c "Print :UISupportedInterfaceOrientations" Info.plist
/usr/libexec/PlistBuddy -c "Print :UIRequiresFullScreen" Info.plist
PlistBuddy kończy się kodem różnym od zera, gdy klucza brakuje, i to samo w sobie jest odpowiedzią w przypadku UIRequiresFullScreen: brak klucza oznacza, że trybu zgodności nigdy nie było.
Należy odnaleźć kontrolery, które ograniczają orientację w kodzie. To one działają dalej po zmianie w Info.plist, a ich brak sprawia, że ta zmiana staje się niebezpieczna.
rg 'supportedInterfaceOrientations|shouldAutorotate' --type swift
Pusty wynik w połączeniu z wąską deklaracją w Info.plist to dokładnie ten profil, który się psuje: aplikacja pozostaje wyłącznie pionowa jedynie za sprawą property list, więc poszerzenie deklaracji usuwa jedyne istniejące ograniczenie.
Następnie trzeba obejrzeć aplikację na obu idiomach. Usterka jest wizualna, a sygnał automatyczny słaby. Test UI, który przechodzi przez ekran i sprawdza jego zawartość, przechodzi w każdej orientacji. Szuka się widoku, który obraca się mimo że wcześniej nie mógł, co oznacza uruchomienie kompilacji na iPhone’a i fizyczne obrócenie urządzenia albo symulatora po zmianie w Info.plist.
Przechwytywanie multimediów, skanowanie dokumentów, pola podpisu, gry i wszystko, co opiera się na płótnie o stałych proporcjach, to miejsca, w których nieoczekiwana rotacja kosztuje najwięcej — i zarazem te, w których nadpisania na poziomie kontrolera mają najbardziej oczywisty sens.
UIRequiresFullScreen jest wydrążane, a nie wycofywane
Cztery z pięciu otwartych problemów dotyczą UIRequiresFullScreen.1 Klucz, który wyłącza aplikację z wielozadaniowości na iPadzie, jest dziś warunkiem, przy którym dostarczanie zmian rozmiaru działa nieprawidłowo.
Nie został wycofany. Dokumentacja UIRequiresFullScreen wskazuje dostępność w iOS 9.0 oraz iPadOS 9.0, bez oznaczenia wycofania, niedostępności czy bety.3 UISupportedInterfaceOrientations również nie jest wycofane — dostępne jest od iOS 3.2.4
To zestawienie warto nazwać po imieniu. Aplikacja ustawiająca UIRequiresFullScreen w 2026 roku kompiluje się bez ostrzeżenia, trafia do wydania bez informacji o migracji i ląduje w trybie zgodności, który Apple stale zawęża. Dokumentacja opisuje już, co ten tryb oznacza w nowoczesnych systemach: w iPadOS 26 i nowszych na iPadach obsługujących tryb Windowed Apps oraz w iPadOS 16 lub nowszym na iPadach obsługujących Stage Manager system „utrzymuje spójny rozmiar sceny aplikacji, ale nie prezentuje jej sceny na pełnym ekranie”.3
Klucz nie robi już tego, co mówi jego nazwa. Nie został wycofany i nic w kompilacji o tym nie powie.
Wzorzec: decyduje SDK, z którym zbudowano aplikację
Każdy z powyższych wpisów ma wspólny warunek, a nie jest nim wersja systemu. Każdy dotyczy aplikacji „zbudowanych z SDK iOS 27”.1
To samo źródło, inny plik binarny, inne zachowanie. W tym wydaniu powtarza się to wielokrotnie: obrazy elementów menu zależą od SDK, z którym wykonano linkowanie — trzy odmienne zachowania na przestrzeni dwóch generacji SDK. Z kolei odmowa dostępu do kontenerów innego zespołu w macOS 27 wygląda na przypadek odwrotny, czyli politykę na poziomie systemu bez zastrzeżenia dotyczącego SDK — i właśnie dlatego to rozróżnienie warto sprawdzić, zamiast je zakładać.
Praktyczna konsekwencja dla testów: kompilacja z SDK iOS 26 i kompilacja z SDK iOS 27 to dwa różne przedmioty badania. Jeśli macierz CI zawiera jedną wersję Xcode, testuje tylko jeden z nich.
Co robić teraz
Trzeba rozstrzygnąć, czy ciągła zmiana rozmiaru jest w ogóle potrzebna. Jeśli aplikacja na iPada deklaruje już wszystkie cztery orientacje, nic z tego jej nie dotyczy. Obejście ma znaczenie tylko wtedy, gdy orientacje ograniczono świadomie.
Stosując obejście, trzeba połączyć je z nadpisaniami na poziomie kontrolera. Zmiana w Info.plist jest sufitem; ograniczenie musi przenieść się do supportedInterfaceOrientations w tych kontrolerach, które go potrzebują, z rozróżnieniem na idiom.
UIRequiresFullScreen należy sprawdzić osobno. Dotyczą go cztery otwarte problemy, a kompilacja go nie sygnalizuje. Warto przejrzeć greppem pliki Info.plist, w tym w każdym targecie, którego nie uważa się za aplikację na iPada, ponieważ jeden z problemów obejmuje aplikacje wyłącznie na iPhone’a uruchamiane na iPadzie.
Należy spodziewać się zniknięcia blokady. Apple stwierdza, że orientacje nie powinny już warunkować ciągłej zmiany rozmiaru. Gdy to nastąpi, powód deklarowania wszystkich czterech zniknie, ale poszerzony zestaw orientacji pozostanie w Info.plist, dopóki ktoś go nie usunie. Warto zostawić komentarz wyjaśniający, po co się tam znalazł.
Przed działaniem trzeba sprawdzić informacje o wydaniu ponownie. Jeden z tych sześciu wpisów już przeszedł ze znanych problemów do rozwiązanych. Ten wpis odzwierciedla stan bety 4 na 2 sierpnia 2026.
Najważniejsze wnioski
Dla twórców aplikacji na iPada:
- Zadeklarowane orientacje wciąż blokują ciągłą zmianę rozmiaru w becie 4, mimo że Apple twierdzi, iż nie powinny. Należy traktować to jako błąd z obejściem, a nie jako nowe zachowanie.
- Obejście poszerza sufit orientacji w całej aplikacji. Trzeba dodać nadpisania supportedInterfaceOrientations na poziomie kontrolera, inaczej kompilacja na iPhone’a zacznie się obracać.
- Cztery otwarte problemy dotyczą UIRequiresFullScreen, które dostarcza ciągłe, a nie dyskretne aktualizacje rozmiaru.
Dla każdego, kto utrzymuje starszą aplikację:
- UIRequiresFullScreen nie jest wycofane i nie generuje żadnego ostrzeżenia, choć zachowanie, o które prosi, wciąż się kurczy. Trzeba sprawdzić je wprost.
- Każdy z opisanych problemów jest uwarunkowany zbudowaniem aplikacji z SDK iOS 27, a nie systemem, z którego korzysta użytkownik.
Często zadawane pytania
Czy zadeklarowane orientacje przestały blokować ciągłą zmianę rozmiaru?
Nie w becie 4. Apple stwierdza, że „począwszy od iOS 27, obsługiwane orientacje interfejsu nie powinny już być warunkiem ciągłej zmiany rozmiaru”, i umieszcza to stwierdzenie wśród znanych problemów, ponieważ obecne zachowanie nadal je od nich uzależnia.1
Na czym dokładnie polega obejście?
Na zadeklarowaniu wszystkich czterech orientacji interfejsu w UISupportedInterfaceOrientations.1 Trzeba połączyć je z nadpisaniami supportedInterfaceOrientations w tych view controllerach, które mają pozostać ograniczone, ponieważ system przecina zbiór z poziomu całej aplikacji ze zbiorem każdego kontrolera.2
Czy wpłynie to na kompilację na iPhone’a?
Jeśli wydawana jest aplikacja uniwersalna, a ograniczenie orientacji opiera się wyłącznie na Info.plist — tak. Apple zaleca całkowite wyłączenie orientacji odwróconej dla idiomu iPhone’a i zaznacza, że system ignoruje ją na urządzeniach bez przycisku Home.24
Czy UIRequiresFullScreen jest wycofane?
Nie. Jego dokumentacja wskazuje dostępność w iOS i iPadOS 9.0 bez oznaczenia wycofania.3 Dotyczą go cztery z opisanych tu otwartych problemów, więc braku oznaczenia wycofania nie należy odczytywać jako rekomendacji.
Czy usunąć obejście, gdy Apple naprawi blokadę?
Należy usunąć tę część, która przestała być potrzebna, a zachować tę, która chroni. Gdy zadeklarowane orientacje przestaną warunkować ciągłą zmianę rozmiaru, powód wypisywania wszystkich czterech zniknie i UISupportedInterfaceOrientations można będzie zawęzić z powrotem do tego, co aplikacja faktycznie obsługuje. Nadpisania supportedInterfaceOrientations na poziomie kontrolera powinny pozostać niezależnie od wszystkiego, ponieważ wyrażanie ograniczeń orientacji tam, gdzie ograniczenie przynależy, jest trwalsze niż poleganie na sufcie z poziomu całej aplikacji.
Trybem awarii, którego trzeba uniknąć, jest sytuacja odwrotna: zawężenie Info.plist z powrotem przy jednoczesnym zapomnieniu, że to nadpisania były jedyną rzeczą utrzymującą ekran przechwytywania w pionie.
Jak rozpoznać, czy aplikacja obsługuje obecnie ciągłą zmianę rozmiaru?
Wystarczy zmienić rozmiar okna na iPadzie i zobaczyć, czy układ podąża za przeciąganiem, czy dopasowuje się skokowo na końcu. Podążanie oznacza ciągłą zmianę rozmiaru. Jeśli układ przeskakuje, trzeba sprawdzić dwie rzeczy: czy ustawiono UIRequiresFullScreen, co całkowicie wyłącza dynamiczną zmianę rozmiaru, oraz czy UISupportedInterfaceOrientations wymienia wszystkie cztery orientacje, co jest warunkiem opisanym w tym znanym problemie.13
Czy budowanie ze starszym SDK pozwala tego wszystkiego uniknąć?
Każdy wpis jest uwarunkowany zbudowaniem aplikacji z SDK iOS 27.1 Starszy SDK pozwala uniknąć tych konkretnych problemów i opóźnia docelową zmianę, ale jej nie zapobiega.
Źródła
-
Apple, “iOS & iPadOS 27 Beta 4 Release Notes,” UIKit. Znane problemy: radar 166422120 (orientacje blokujące ciągłą zmianę rozmiaru, wraz z obejściem opartym na czterech orientacjach), 178560235, 178562971 oraz 178558224 (
UIRequiresFullScreenotrzymujące ciągłe, a nie dyskretne aktualizacje rozmiaru: na iPadzie, dla aplikacji wyłącznie na iPhone’a uruchamianych na iPadzie oraz w iPhone Mirroring), a także 178555304 (sceny iPhone Mirroring obsługujące wszystkie orientacje niezależnie od deklaracji). Problemy rozwiązane: radar 178559386 (boundsUIScreen.mainzmieniające się przy zmianie rozmiaru podUIRequiresFullScreen), który był znanym problemem we wcześniejszej becie. Przynależność do sekcji ponownie zweryfikowana na podstawie pliku JSON bety 4 dnia 2026-08-02. Aktualizacja 2026-08-24: ponownie zweryfikowano na podstawie pliku JSON edycji bety 7 – 166422120 oraz cała grupa wpisów oUIRequiresFullScreenfigurują teraz wśród problemów rozwiązanych (przeniesienie nastąpiło najpóźniej w edycji bety 6 według kopii archiwalnych), a lista znanych problemów UIKit jest pusta. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Apple, “UIViewController.supportedInterfaceOrientations.” Źródło reguły przecięcia zbiorów cytowanej w całości powyżej, zgodnie z którą system porównuje orientacje obsługiwane przez view controller z orientacjami aplikacji (z
Info.plistalbo z app delegate) oraz urządzenia. Także źródło informacji o wartościach domyślnych zależnych od idiomu, o warunku wstępnymshouldAutorotateoraz o zaleceniu wyłączenia orientacji odwróconej dla idiomu iPhone’a. ↩↩↩↩↩↩↩ -
Apple, “UIRequiresFullScreen.” Dostępne w iOS 9.0 i iPadOS 9.0, bez oznaczenia wycofania, niedostępności czy bety na dzień 2026-08-02. Źródło opisu trybu zgodności, w tym zachowania w trybie Windowed Apps w iPadOS 26 i nowszych oraz w Stage Manager w iPadOS 16 i nowszych. ↩↩↩↩↩↩↩
-
Apple, “UISupportedInterfaceOrientations.” Dostępne w iOS 3.2 i iPadOS 3.2, bez oznaczenia wycofania. Źródło czterech wartości orientacji oraz uwagi, że system ignoruje opcję odwróconą na urządzeniach bez przycisku Home. ↩↩↩↩