Забезпечення сумісності мобільного додатку з новими пристроями
Apple випустила iPhone 16 з новим формфактором та Dynamic Island замість notch. Через тиждень користувачі почали надсилати скриншоти: статус-бар перекриває контент, кнопки ушли під Home Indicator, камера закриває частину інтерфейсу. Додаток не зламався — він просто не знав про нові Safe Area insets.
Що конкретно ламається при виході нового пристрою
Safe Area і Dynamic Island. На iOS Safe Area insets залежать від моделі пристрою. Hardcoded відступи — UIEdgeInsets(top: 44, left: 0, bottom: 34, right: 0) — невірні вже для трьох поколінь iPhone. Правильно: view.safeAreaInsets або safeAreaLayoutGuide в Auto Layout. В SwiftUI — .ignoresSafeArea() з явним указанням краї, не глобально.
Display cutout на Android. З Android 9 з'явився DisplayCutout API. Пристрої з вирізом під камеру (Pixel, Samsung A-серія, Xiaomi) мають WindowInsets.getDisplayCutout(). Якщо додаток не враховує LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES або NEVER, контент піде під виріз на повноекранних фрагментах.
Зміна aspect ratio. Флагмани 2023–2024 років мають ratio 19.5:9 та 20:9. Якщо layoutи сверстані під 16:9 з фіксованими висотами — контент або розтягується, або з'являються чорні смуги. На Android тест через <activity android:maxAspectRatio> — якщо не указано, ОС може обмежити додаток letterbox режимом.
Foldable і великі екрани. Samsung Fold, Pixel Fold — додаток отримує configuration change при розгортанні. Якщо Activity не обробляє configChanges="screenSize|smallestScreenSize|screenLayout|orientation", відбувається пересоздання з втратою стану. Jetpack WindowManager FoldingFeature дозволяє адаптувати layout під стан петлі.
Процес перевірки сумісності
Новий пристрій тестуємо по шарам:
-
Симулятор/емулятор — первинна перевірка layout на новому формфакторі без реального пристрою. Xcode Simulator для iPhone 16 Pro з'являється з релізом Xcode. Android Emulator — створюємо AVD з потрібною роздільною здатністю та щільністю.
-
Firebase Test Lab / BrowserStack — прогон UI-тестів на реальному парку пристроїв. Особливо важливо для Android: фрагментація величезна, емулятор не відтворює специфічні баги кастомних launcher'ів та оболонок.
-
Реальний пристрій — для touch, Face ID, камери, NFC. Деякі баги відтворюються лише на залізі.
Для iOS: перевіряємо traitCollection.horizontalSizeClass і verticalSizeClass, UIScreen.main.bounds (хоча для layout краще не покладатися на глобальний bounds — використовуємо container-relative layout).
Для Android: WindowMetricsCalculator.computeCurrentWindowMetrics(activity) з Jetpack WindowManager замість застарілого Display.getSize().
Типові знахідки при аудиті
- ScrollView без
contentInsetAdjustmentBehavior = .automatic— контент піде під Navigation Bar -
WebViewз фіксованою висотою замість constraint доsafeAreaLayoutGuide.bottomAnchor - Splash screen з hardcoded розміром — не масштабується на Pro Max / Ultra
-
getStatusBarHeight()через reflection у старому Android-коді — повертає 0 на деяких нових пристроях
Терміни
Аудит сумісності з новими пристроями та правка критичних багів — 2–3 дні. Якщо додаток спочатку писався без Auto Layout / ConstraintLayout (старий frame-based код) — може потребуватися значний рефакторинг.







