Как показали на WWDC 26, при зеркальном отображении приложения для iPhone на Mac через функцию iPhone Mirroring, размер его окна можно свободно изменять. Одновременно с этим, приложения для iPhone, работающие на iPad, также получат возможность изменять размер окна. Даже без обновления физического устройства до бета-версии новой ОС, разработчики уже могут оценить это изменение в предварительных версиях Xcode 27 или в среде симулятора iOS 27 в Device Hub.
Однако влияние этого обновления выходит далеко за рамки простого изменения размера окон приложений для iPhone. Оно меняет представление многих разработчиков о системе компоновки. Некоторые характеристики, которые ранее часто использовались в качестве параметров компоновки, такие как horizontalSizeClass, больше не подходят в качестве основного критерия определения ширины окна.
Так является ли это изменение внезапным сдвигом или неизбежным результатом долгосрочной эволюции системы компоновки Apple? В этой статье мы рассмотрим этот вопрос.
Моё приложение для iPhone стало выглядеть некрасиво
Недавно я занимался рефакторингом своего старого проекта, переписывая всё приложение с использованием новых идей программирования и API.
Увидев поведение приложения для iPhone с изменяемым размером, показанное на WWDC 26, я сразу же протестировал, как моё собственное приложение ведёт себя в этом сценарии. Поскольку в приложении уже была зарезервирована логика адаптации для iPhone, iPad и macOS, я изначально предположил, что после растягивания ширины окна в Device Hub существующей адаптивной компоновки будет достаточно для обработки изменений.
Но, к моему удивлению, NavigationSplitView не переключился с одноколоночной компоновки на многоколоночную, и компоненты, связанные с вкладками, также не преобразовались в ожидаемое представление.
Проверив свойство horizontalSizeClass, я обнаружил, что независимо от изменения размера окна, оно всегда остаётся компактным.
Однако, когда приложение запускается на iPad с использованием идиомы pad, horizontalSizeClass всё ещё изменяется в определённом диапазоне по мере изменения размера окна. Если удалить семейство устройств iPad и запустить приложение на iPad в режиме совместимости только с iPhone, его поведение станет намного ближе к поведению хоста iPhone в Device Hub.
Сначала я подозревал, что это нерешенная проблема в бета-версии 1. Только посмотрев сессию WWDC 26 «Модернизация вашего UIKit приложения», я понял, что это на самом деле было преднамеренным дизайнерским решением Apple.
Это не ошибка бета-версии: новый контракт с WWDC26
В сессии 278 «Модернизация вашего UIKit приложения» Apple явно переносит приложения для iPhone в среду динамического изменения размера:
- В функции «Зеркалирование iPhone» на Mac окно iPhone можно свободно изменять в размере.
- Приложения, работающие только с iPhone на iPad, также попадают в среду с изменяемым размером.
- Приложения должны адаптироваться к произвольным размерам сцены во время выполнения, а не предполагать фиксированное соотношение сторон устройства.
UIScreen.mainи границы экрана больше не являются надежными. Разработчикам следует использовать эффективную геометрию оконной сцены или фактический доступный размер представления или родительского представления.userInterfaceIdiomбольше не подходит в качестве основы для принятия решений по компоновке.- Приложения для iPhone, работающие на iPad или в режиме зеркального отображения на Mac, могут по-прежнему работать в соответствии с телефонным интерфейсом, что означает, что телефонный интерфейс больше не эквивалентен узкоэкранной компоновке.
- Ориентация также больше не является надежной. В среде с изменяемым размером поддерживаемые ориентации ближе к настройкам; даже если соотношение сторон окна изменяется, система может по-прежнему сохранять портретную ориентацию.
- Для точного управления компоновкой в первую очередь следует использовать размер родительского представления.
Это объясняет неинтуитивное поведение, с которым я столкнулся ранее: даже после увеличения ширины окна horizontalSizeClass в хосте iPhone может оставаться compact.
Это не ошибка бета-версии. Это результат того, что Apple намеренно разделяет «семантику хоста» и «доступное геометрическое пространство».
Остаётся ли horizontalSizeClass надёжным?
Короткий ответ: да.
Однако он надёжно отражает лишь обобщённые характеристики текущего окружения трейтов, а не фактическую ширину окна.
Это, пожалуй, одна из самых распространённых ошибок в этом году. Более широкое окно на iPhone не означает, что система обязательно переключит horizontalSizeClass на regular. И наоборот, даже относительно узкое окно iPad может давать совершенно разные результаты в зависимости от его идиомы, сцены, представления или среды контейнера.
Для разработчиков действительно важное изменение заключается не в том, что «iPhone стал iPad», а в следующем:
userInterfaceIdiom: описывает только семантику хоста, в рамках которого работает приложение. Его больше не следует использовать в качестве основы для принятия решений по компоновке.horizontalSizeClass: это контекстная оценка системой среды трейтов, а не непрерывный датчик ширины.- Геометрия представления или сцены является более точной основой для компоновки при работе с произвольными размерами окон, изменяющимися соотношениями сторон, плавающими окнами и сценариями зеркального отображения.
Поэтому horizontalSizeClass по-прежнему подходит для выражения семантики системного контейнера, например, следует ли сворачивать меню или доступны ли системные вкладки или боковые панели. Но для собственных контрольных точек компоновки приложения, таких как «переключиться на двухколоночную компоновку после определенной ширины» или «показать боковую навигацию», решение должно основываться на фактическом доступном размере текущего корневого представления, контейнерного представления или сцены.
От устройства к сцене, от ориентации к доступному пространству
Если мы посмотрим только на WWDC 26, это изменение легко можно понять как новую проблему, возникшую с появлением функции изменения размера на iPhone.
Но если мы соединим точки за последние несколько лет, мы увидим, что Apple на самом деле все это время двигалась в одном направлении: постоянно уменьшая важность «типа устройства + ориентации экрана» как основы для решений по компоновке и постепенно направляя разработчиков к сценам, иерархии характеристик и доступному пространству.
- 2014: Apple представила Size Class в iOS 8. В этом году на сессии 278 вновь была подчеркнута та же идея дизайна: поворот устройства по сути является просто изменением границ.
- 2019: Многооконный режим iPad и
UISceneразрушили традиционное предположение о том, что «одно приложение имеет только один экземпляр пользовательского интерфейса». Сцена начала иметь свой собственный жизненный цикл, восстановление состояния, информацию об экране и геометрии. - 2022: Обновления iPadOS 16, приблизившие iPad к настольному классу устройств, еще больше отдалили интерфейсы iPad от просто «увеличенных приложений iPhone» и приблизили их к более плотным, похожим на настольные компьютеры интерфейсам для повышения производительности, заложив основу для последующего дизайна с переменным пространством.
- 2023: Сессия «Unleash the UIKit trait system» сделала это направление еще более ясным. Информация об окружении была преобразована в контекстные данные, которые распространяются слой за слоем через сцену, окно, презентацию, контроллер представления и представление, а не существуют как единый факт на уровне устройства. Это также объясняет, почему значение
horizontalSizeClass, которое разработчики считывают в окне, листке или разделенной колонке iPad, часто отличается от интуитивного. - 2024: Tab Bar и Sidebar стали рассматриваться как разные представления одной и той же иерархии навигации в разных пространственных условиях, что позволило создать единый язык для последующего автоматического изменения навигации.
- 2025: iPadOS еще больше сблизилась с macOS, окна, строки меню, указатели и многооконные рабочие процессы стали больше похожи на настольные приложения.
- 2026: Приложения для iPhone перешли в среду с изменяемым размером, и предположение о том, что «приложения для iPhone обслуживают только фиксированное соотношение сторон телефона», официально стало недействительным.
Полноэкранный режим iPad демонстрирует ту же тенденцию
Изменения в полноэкранном режиме на iPad фактически указывают на ту же тенденцию.
Apple не лишила пользователя права выбирать полноэкранный режим работы, но постепенно возвращает разработчику возможность блокировать приложение в старом режиме совместимости с помощью UIRequiresFullScreen.
В iPadOS 26 пользователи по-прежнему могут выбирать между полноэкранными приложениями, оконными приложениями и Stage Manager через Настройки или Центр управления. Но для разработчиков UIRequiresFullScreen уже определен как устаревший режим совместимости и будет игнорироваться системой в будущем.
Другими словами, полноэкранный режим постепенно превращается из «того, что разработчики могут потребовать» в «то, что определяется совместно пользователем и системой». Подробнее об этом см. в документации Apple TN3192 и UIRequiresFullScreen.
Это возвращает полноэкранный режим iPad и изменение размера iPhone к одному и тому же основному принципу: разработчики могут задавать предпочтения, минимальные размеры и временные блокировки ориентации, но им больше не следует предполагать, что они владеют фиксированным и неизменным холстом.
Возвращаясь к проекту: разработка собственной стратегии компоновки с использованием геометрии
После понимания этих правил я начал пересматривать, как мое приложение должно реагировать на изменение размера экрана iPhone.
Хотя можно инжектировать \.horizontalSizeClass = .regular в поддерево SwiftUI на основе геометрии сцены, позволяя некоторым контейнерам использовать семантику регулярных элементов, это не подходит в качестве глобальной стратегии.
Такой подход влияет на все представления в этом поддереве, которые считывают значение из окружения. При этом разные компоненты по-разному ведут себя при сочетании «тип устройства — iPhone» и «принудительно заданный обычный класс размера».
Например, NavigationSplitView может расширять свою боковую панель, но в моих тестах TabView(.sidebarAdaptable) не становится автоматически боковой панелью в стиле iPad.
Это не означает, что API для включения боковой панели вкладок, представленный UIKit в iOS 27, не имеет ценности. Скорее, это показывает, что «широкое окно iPhone» и «среда навигации iPad» — это не одно и то же.
Другими словами: широкоэкранный iPhone — это всё ещё адаптивное отображение интерфейса iPhone, а не полноценный интерфейс iPad.
Учитывая сценарии моего приложения, я обнаружил, что идея Apple 2024 года о том, что «панель вкладок и боковая панель — это разные представления одной и той же иерархии навигации», очень хорошо подходит для проекта.
Поэтому я определил следующую стратегию для приложения:
- Использовать геометрию для определения того, перешла ли текущая среда в широкоэкранное состояние.
- На iPhone в широкоэкранном режиме отображать пользовательскую боковую панель и скрывать панель вкладок.
- Кнопки в боковой панели по-прежнему управляют переключением вкладок в зависимости от состояния.
- В iPadOS не включать эту специфичную для iPhone логику; вместо этого отдавать приоритет адаптации системных компонентов в соответствии с их собственными характеристиками и геометрией.
- В macOS полностью удалить структуру вкладок и использовать навигацию через боковую панель.
Эра фиксированного холста закончилась
В будущем разработчики смогут задавать скорее предпочтения, чем полностью контролировать интерфейс.
Например:
- Используйте
UISceneSizeRestrictionsдля указания предпочтительного минимального размера сцены. - В SwiftUI используйте
windowResizability(_:)и минимальный размер содержимого для указания предпочтений размера окна. - Используйте
prefersInterfaceOrientationLockedдля указания необходимости временной блокировки ориентации. - Отслеживайте изменения геометрии сцены с помощью
windowScene(_:didUpdateEffectiveGeometry:). - Используйте
UIWindowSceneGeometry.isInteractivelyResizingилиonInteractiveResizeChange(_:)в SwiftUI, чтобы различать интерактивный процесс изменения размера и конечное состояние.
Теперь пользователи сами решают, как будет отображаться приложение, в то время как разработчикам необходимо заранее учитывать больше возможных форм представления. Хотя все больше и больше системных компонентов теперь обладают мощными адаптивными возможностями, и SwiftUI значительно снизил барьер для создания адаптивных интерфейсов, количество сценариев, которые должны обрабатывать разработчики, фактически увеличилось.
Эпоха фиксированного холста подходит к концу, а эра построения интерфейсов с учетом доступного пространства только начинается.

