Płynna zmiana rozmiaru na iPadzie w iOS 27: obejście ma swoją cenę
Informacje o wydaniu iOS 27 zawierają jednozdaniowe obejście dla aplikacji iPadowych, które nie obsługują płynnej zmiany rozmiaru: należy zadeklarować wszystkie cztery orientacje interfejsu w pliku Info.plist.1 Nota przemilcza jednak fakt, że system przecina tę deklarację obowiązującą w całej aplikacji z orientacjami obsługiwanymi przez każdy kontroler widoku.2 Poszerzenie zestawu na poziomie aplikacji poszerza go wszędzie, także na iPhonie — chyba że każdy ograniczony kontroler widoku nadpisze supportedInterfaceOrientations.
Wersja tej zmiany, która trafia do nagłówków, również błędnie opisuje stan bieżący. Intencją Apple jest to, by zadeklarowane orientacje przestały warunkować płynną zmianę rozmiaru. Nota, która tę intencję zapisuje, trafiła do sekcji Known Issues — bo w becie 4 orientacje wciąż ją 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 udokumentował w tym samym miejscu.
W skrócie
W iOS i iPadOS 27 Beta 4 aplikacja iPadowa zbudowana przy użyciu SDK iOS 27, której UISupportedInterfaceOrientations pomija którąkolwiek z czterech orientacji, jest traktowana jako niepodlegająca płynnej zmianie rozmiaru. Apple wymienia to jako znany problem obok stwierdzenia, że orientacje „nie powinny już być warunkiem płynnej zmiany rozmiaru”.1 Udokumentowane obejście polega na zadeklarowaniu wszystkich czterech. To poszerza zestaw orientacji w całej aplikacji, a system ustala obrót, porównując orientacje aplikacji z orientacjami każdego kontrolera widoku.2 Cztery kolejne znane problemy dotyczą UIRequiresFullScreen: dostarczane są przy nim ciągłe aktualizacje rozmiaru tam, gdzie zamierzone były dyskretne zmiany UIScreen.1 Ani UIRequiresFullScreen, ani UISupportedInterfaceOrientations nie zostały wycofane.34
Co naprawdę mówią informacje o wydaniu
Dotyczy tego sześć wpisów w sekcji UIKit informacji o wydaniu iOS i iPadOS 27 Beta 4; pięć z nich pozostaje otwartych.1
Sama blokada, w sekcji Known Issues:
„Na iPadzie, jeśli aplikacja iPadowa jest zbudowana przy użyciu SDK iOS 27, a jej
UISupportedInterfaceOrientationsnie zawiera wszystkich czterech orientacji interfejsu, aplikacja jest traktowana jako niepodlegająca płynnej zmianie rozmiaru. Począwszy od iOS 27 obsługiwane orientacje interfejsu nie powinny już być warunkiem płynnej zmiany rozmiaru.”
Warto zwrócić uwagę na czas gramatyczny w drugim zdaniu. „Nie powinny już być warunkiem” opisuje zachowanie zamierzone. Wpis figuruje jako znany problem właśnie dlatego, że zachowanie w wydanej wersji jeszcze nie odpowiada intencji.
To rozróżnienie zmienia to, co należy zrobić. Gdyby orientacje faktycznie przestały warunkować zmianę rozmiaru, zalecenie brzmiałoby: usunąć obejścia. Ponieważ nadal ją warunkują, zalecenie brzmi: zastosować obejście i spodziewać się, że powód jego istnienia zniknie.
Cztery znane problemy wokół UIRequiresFullScreen:
Aplikacja iPadowa zbudowana przy użyciu SDK iOS 27, która ustawia UIRequiresFullScreen, otrzymuje ciągłe aktualizacje rozmiaru, podczas gdy „każda zmiana rozmiaru powinna zamiast tego być dostarczana jako dyskretna zmiana na nowy UIScreen z zaktualizowanymi granicami”. To samo dotyczy aplikacji przeznaczonej wyłącznie na iPhone’a działającej na iPadzie, a także sytuacji w iPhone Mirroring.1
Czwarty wpis obejmuje obsługę orientacji w iPhone Mirroring: aplikacja zbudowana przy użyciu SDK iOS 27 otrzymuje scenę obsługującą wszystkie orientacje „niezależnie od orientacji zadeklarowanych w UISupportedInterfaceOrientations lub zwróconych przez UIViewController.supportedInterfaceOrientations”, podczas gdy te „powinny być respektowane, dopóki użytkownik nie rozpocznie zmiany rozmiaru okna”.1
Jeden rozwiązany: wcześniejszy problem, w którym granice UIScreen.main zmieniały się przy zmianie rozmiaru pod UIRequiresFullScreen, figuruje teraz w sekcji Resolved Issues.1 We wcześniejszej becie był aktywnym znanym problemem. Kto pracuje na notatkach sprzed kilku tygodni, powinien to sprawdzić, zanim je powtórzy.
Co daje płynna zmiana rozmiaru
Zanim zważymy koszt, warto precyzyjnie nazwać to, co jest blokowane, bo określenie „płynnie zmieniający rozmiar” niesie tu konkretną treść.
Okno na iPadzie może zmieniać rozmiar na dwa sposoby. Może przeskakiwać między dyskretnymi stanami — tak działa 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 przez użytkownika.
Różnicę widać pod palcem. Aplikacja obsługująca płynną zmianę rozmiaru przebudowuje układ w trakcie ruchu okna. Aplikacja bez tej obsługi zachowuje układ i doskakuje dopiero na końcu, co obok aplikacji systemowych, które tak nie robią, sprawia wrażenie ociężałości.
Apple od lat zawęża ścieżkę zgodności. UIRequiresFullScreen pojawiło się w iOS 9, by całkowicie wypisać aplikację z wielozadaniowości iPada i dynamicznej zmiany rozmiaru.3 Stage Manager w iPadOS 16 i tryb Windowed Apps w iPadOS 26 kolejno rozszerzały możliwości okna, a dokumentacja opisuje dziś tryb zgodności przez pryzmat tego, czego odmawia, a nie tego, co daje.
Pytanie, na które odpowiada obejście, brzmi więc: czy aplikacja iPadowa uczestniczy w nowoczesnym okienkowaniu, czy siedzi w trybie, który Apple konsekwentnie zawęża. To jest warte zmiany w Info.plist. Nie jest natomiast warte zmiany niezabezpieczonej — o czym mówi kolejna sekcja.
Cena obejścia
Obejście Apple mieści się w jednym zdaniu: zadeklarować w Info.plist wszystkie cztery orientacje interfejsu.1 Konsekwencja opisana jest na innej stronie.
Dokumentacja UIViewController.supportedInterfaceOrientations wyjaśnia, jak zapada decyzja o obrocie:2
„Aby ustalić, czy dokonać obrotu, system porównuje obsługiwane orientacje kontrolera widoku z obsługiwanymi orientacjami aplikacji — określonymi przez plik
Info.plistalbo [metodę] delegata aplikacji — oraz z obsługiwanymi orientacjami urządzenia.”
Trzy zbiory, przecięte. Deklaracja w Info.plist to sufit, nie instrukcja. Aplikacja, która pozostawała wyłącznie w orientacji pionowej dzięki wpisaniu jednej orientacji w Info.plist i nigdy niczego nie nadpisywała na poziomie kontrolera widoku, traci swoje ograniczenie w chwili zastosowania obejścia.
W aplikacji uniwersalnej odbija się to na iPhonie tak samo jak na iPadzie. A własne wskazówki Apple przemawiają tam przeciwko szerokiej deklaracji: w kwestii orientacji odwróconej — „Najlepszą praktyką jest włączenie jej dla idiomu iPad. Urządzenia z iOS bez przycisku Home, takie jak iPhone 12, nie obsługują tej orientacji. Dla idiomu iPhone należy wyłączyć ją całkowicie”.2 Dokumentacja Info.plist mówi to samo z drugiej strony, odnotowując, że system ignoruje orientację odwróconą „na urządzeniach bez przycisku Home”.4
Uczciwa instrukcja składa się zatem z dwóch kroków, nie 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, że aplikacja uniwersalna dostała polecenie obracania się do góry nogami na iPhonie po to, by uzyskać określone zachowanie okien na iPadzie. Ten błąd nie objawi się jako crash ani błąd kompilacji. Objawi się jako widok aparatu, który obraca się komuś w rękach.
Warto też pamiętać, że domyślne wartości supportedInterfaceOrientations różnią się w zależności od idiomu, a system sięga po tę właściwość tylko wtedy, gdy shouldAutorotate zwraca true.2 Jeśli ta metoda została nadpisana, warto ponownie przeczytać opis tej interakcji, zanim uzna się swoje ograniczenie za trwałe.
Jak sprawdzić, czy problem dotyczy naszej aplikacji
Nic z tego nie wywoła błędu kompilacji, więc audyt trzeba przeprowadzić ręcznie. Trzy kontrole, uszeregowane według tego, ile czasu oszczędzają.
Sprawdzić, co faktycznie deklaruje Info.plist — dla każdego targetu. Klucze orientacji bywają ustawiane raz, przy tworzeniu projektu, i nikt do nich później nie wraca, a aplikacja uniwersalna może nieść odrębne deklaracje dla iPhone’a i iPada przez 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 działanie z niezerowym kodem, gdy klucza brakuje — a to samo w sobie jest odpowiedzią w przypadku UIRequiresFullScreen: brak klucza oznacza, że nigdy nie było się w trybie zgodności.
Znaleźć kontrolery, które ograniczają orientację w kodzie. To one działają dalej po zmianie w Info.plist, a ich brak jest tym, co czyni tę zmianę niebezpieczną.
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 jest wyłącznie pionowa jedynie za sprawą listy właściwości, więc poszerzenie deklaracji usuwa jedyne istniejące ograniczenie.
Następnie obejrzeć aplikację — na obu idiomach. Usterka jest wizualna, a sygnał automatyczny słaby. Test UI, który przechodzi przez ekran i weryfikuje jego zawartość, przejdzie w każdej orientacji. Szukamy widoku, który się obraca, mimo że wcześniej nie mógł — a to oznacza uruchomienie wersji na iPhone’a i fizyczne obrócenie urządzenia lub symulatora po zmianie w Info.plist.
Przechwytywanie mediów, skanowanie dokumentów, pola podpisu, gry i wszystko, co ma obszar rysowania o stałych proporcjach — tam nieoczekiwany obrót kosztuje najwięcej i tam też nadpisania na poziomie kontrolera mają najbardziej oczywiste miejsce.
UIRequiresFullScreen jest wydrążane, a nie wycofywane
Cztery z pięciu otwartych problemów dotyczą UIRequiresFullScreen.1 Klucz, który wypisuje aplikację z wielozadaniowości iPada, jest teraz warunkiem, przy którym dostarczanie informacji o zmianie rozmiaru działa nieprawidłowo.
Nie został wycofany. Dokumentacja UIRequiresFullScreen podaje dostępność od iOS 9.0 i iPadOS 9.0, bez oznaczenia o wycofaniu, niedostępności ani statusu bety.3 UISupportedInterfaceOrientations, dostępne od iOS 3.2, również nie zostało wycofane.4
To połączenie warto nazwać po imieniu. Aplikacja ustawiająca UIRequiresFullScreen w 2026 roku kompiluje się bez ostrzeżenia, trafia do wydania bez noty migracyjnej i ląduje w trybie zgodności, który Apple wciąż zawęża. Dokumentacja już opisuje, co ten tryb oznacza na nowoczesnych systemach: w iPadOS 26 i nowszych na iPadach obsługujących tryb Windowed Apps oraz w iPadOS 16 i nowszych 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 procesie kompilacji o tym nie poinformuje.
Wzorzec: decyduje powiązanie z SDK
Każdy z powyższych wpisów ma wspólny warunek i nie jest nim wersja systemu. Każdy dotyczy aplikacji „zbudowanych przy użyciu SDK iOS 27”.1
To samo źródło, inny plik binarny, inne zachowanie. W tym wydaniu powtarza się to wielokrotnie: obrazy w elementach menu zależą od tego, z którym SDK zlinkowano aplikację — trzy różne zachowania w dwóch generacjach SDK. Z kolei odmowa dostępu do kontenerów między zespołami w macOS 27 wygląda na przypadek odwrotny: polityka na poziomie systemu, bez zastrzeżenia co do SDK — i właśnie dlatego to rozróżnienie warto sprawdzać, a nie zakładać.
Praktyczna konsekwencja dla testów: wersja zbudowana przy użyciu SDK iOS 26 i wersja zbudowana przy użyciu SDK iOS 27 to dwa różne przedmioty badania. Jeśli macierz CI ma jedną wersję Xcode, testuje tylko jedną z nich.
Co zrobić teraz
Rozstrzygnąć, czy płynna zmiana rozmiaru jest w ogóle potrzebna. Jeśli aplikacja iPadowa już deklaruje wszystkie cztery orientacje, nic z tego jej nie dotyczy. Obejście ma znaczenie tylko wtedy, gdy orientacje zostały celowo ograniczone.
Stosując obejście, połączyć je z nadpisaniami na poziomie kontrolerów. Zmiana w Info.plist to sufit; samo ograniczenie musi przenieść się do supportedInterfaceOrientations na tych kontrolerach, które go wymagają, z rozróżnieniem według idiomu.
Osobno przeprowadzić audyt pod kątem UIRequiresFullScreen. Dotyczą go cztery otwarte problemy, a proces kompilacji nie sygnalizuje jego obecności. Warto przeszukać pliki Info.plist, łącznie z każdym targetem, którego nie uważa się za aplikację iPadową — jeden z problemów obejmuje bowiem aplikacje przeznaczone wyłącznie na iPhone’a działające na iPadzie.
Spodziewać się, że blokada zniknie. Apple deklaruje, że orientacje nie powinny już warunkować płynnej zmiany rozmiaru. Gdy to nastąpi, powód deklarowania wszystkich czterech przestanie istnieć, ale poszerzony zestaw orientacji pozostanie w Info.plist, dopóki ktoś go nie usunie. Warto zostawić komentarz wyjaśniający, skąd się tam wziął.
Sprawdzić noty ponownie przed działaniem. Jeden z tych sześciu wpisów już przeszedł z Known Issues do Resolved Issues. Ten tekst opisuje stan bety 4 na 2 sierpnia 2026.
Najważniejsze wnioski
Dla twórców aplikacji iPadowych:
- Zadeklarowane orientacje nadal warunkują płynną zmianę rozmiaru w becie 4, mimo że Apple twierdzi, iż nie powinny. Trzeba traktować to jak błąd z obejściem, a nie jak nowe zachowanie.
- Obejście poszerza sufit orientacji w całej aplikacji. Trzeba dodać nadpisania supportedInterfaceOrientations na poziomie kontrolerów, inaczej wersja na iPhone’a zacznie się obracać.
- Cztery otwarte problemy dotyczą UIRequiresFullScreen i dostarczania ciągłych zamiast dyskretnych aktualizacji rozmiaru.
Dla każdego, kto utrzymuje starszą aplikację:
- UIRequiresFullScreen nie zostało wycofane i nie generuje żadnego ostrzeżenia, podczas gdy zachowanie, o które prosi, jest wciąż zawężane. Trzeba go szukać wprost.
- Każdy z opisanych tu problemów jest uwarunkowany kompilacją przy użyciu SDK iOS 27, a nie systemem, na którym pracuje użytkownik.
FAQ
Czy zadeklarowane orientacje przestały już warunkować płynną zmianę rozmiaru?
Nie w becie 4. Apple stwierdza, że „począwszy od iOS 27 obsługiwane orientacje interfejsu nie powinny już być warunkiem płynnej zmiany rozmiaru”, i umieszcza to stwierdzenie w sekcji Known Issues, ponieważ obecne zachowanie nadal je od nich uzależnia.1
Na czym właściwie polega obejście?
Na zadeklarowaniu wszystkich czterech orientacji interfejsu w UISupportedInterfaceOrientations.1 Trzeba połączyć je z nadpisaniami supportedInterfaceOrientations w kontrolerach widoku, które muszą pozostać ograniczone, ponieważ system przecina zestaw obowiązujący w całej aplikacji z zestawem każdego kontrolera.2
Czy wpłynie to na wersję 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 i odnotowuje, że system ignoruje ją na urządzeniach bez przycisku Home.24
Czy UIRequiresFullScreen zostało wycofane?
Nie. Dokumentacja podaje dostępność od iOS i iPadOS 9.0, bez oznaczenia o wycofaniu.3 Dotyczą go cztery z opisanych tu otwartych problemów, więc braku takiego oznaczenia nie należy odczytywać jako rekomendacji.
Czy usunąć obejście, gdy Apple naprawi blokadę?
Usunąć tę część, która przestanie być potrzebna, i zachować tę, która chroni. Gdy zadeklarowane orientacje przestaną warunkować płynną zmianę rozmiaru, powód wymieniania wszystkich czterech zniknie i będzie można zawęzić UISupportedInterfaceOrientations z powrotem do tego, co aplikacja faktycznie obsługuje. Nadpisania supportedInterfaceOrientations na poziomie kontrolerów powinny pozostać niezależnie od tego — wyrażanie ograniczeń orientacji tam, gdzie jest ich miejsce, jest trwalsze niż opieranie się na suficie obowiązującym w całej aplikacji.
Scenariusz awarii, którego trzeba uniknąć, jest odwrotny: zawężenie Info.plist z powrotem przy jednoczesnym zapomnieniu, że to właśnie nadpisania jako jedyne trzymały ekran przechwytywania w pionie.
Skąd wiadomo, czy moja aplikacja obsługuje dziś płynną zmianę rozmiaru?
Wystarczy zmienić rozmiar okna na iPadzie i sprawdzić, czy układ podąża za przeciąganiem, czy doskakuje na końcu. Podążanie oznacza płynną zmianę rozmiaru. Jeśli doskakuje, trzeba sprawdzić dwie rzeczy: czy ustawione jest UIRequiresFullScreen, które całkowicie wypisuje aplikację z dynamicznej zmiany rozmiaru, oraz czy UISupportedInterfaceOrientations wymienia wszystkie cztery orientacje — bo to właśnie ten warunek opisuje omawiany znany problem.13
Czy zbudowanie aplikacji przy użyciu starszego SDK pozwala tego wszystkiego uniknąć?
Każdy wpis jest uwarunkowany kompilacją przy użyciu SDK iOS 27.1 Starszy SDK pozwala uniknąć tych konkretnych problemów i odracza nadchodzącą zmianę, ale jej nie zapobiega.
Źródła
-
Apple, “iOS & iPadOS 27 Beta 4 Release Notes,” UIKit. Known Issues: radar 166422120 (orientacje warunkujące płynną zmianę rozmiaru, wraz z obejściem opartym na wszystkich czterech orientacjach), 178560235, 178562971 i 178558224 (
UIRequiresFullScreenotrzymujące ciągłe zamiast dyskretnych aktualizacji rozmiaru — na iPadzie, dla aplikacji przeznaczonych wyłącznie na iPhone’a działających na iPadzie oraz w iPhone Mirroring) oraz 178555304 (sceny iPhone Mirroring obsługujące wszystkie orientacje niezależnie od deklaracji). Resolved Issues: radar 178559386 (graniceUIScreen.mainzmieniające się przy zmianie rozmiaru podUIRequiresFullScreen), który był znanym problemem we wcześniejszej becie. Przynależność do sekcji zweryfikowana ponownie względem pliku JSON bety 4 dnia 2026-08-02. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Apple, “UIViewController.supportedInterfaceOrientations.” Źródło reguły przecięcia zbiorów zacytowanej powyżej w całości, zgodnie z którą system porównuje obsługiwane orientacje kontrolera widoku z orientacjami aplikacji (z
Info.plistlub od delegata aplikacji) oraz urządzenia. Także źródło informacji o wartościach domyślnych zależnych od idiomu, o warunkushouldAutorotateoraz o zaleceniu wyłączenia orientacji odwróconej dla idiomu iPhone. ↩↩↩↩↩↩↩ -
Apple, “UIRequiresFullScreen.” Dostępne od iOS 9.0 i iPadOS 9.0, bez oznaczenia o wycofaniu, niedostępności ani statusu 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 od iOS 3.2 i iPadOS 3.2, bez oznaczenia o wycofaniu. Źródło czterech wartości orientacji oraz uwagi, że system ignoruje opcję orientacji odwróconej na urządzeniach bez przycisku Home. ↩↩↩↩