iOS'ta resizability: uygulamanız hangi cihazda çalıştığını bilmediğinde

Beş tasarım ilkesi, her biri kodla: pencere boyutlandırma çağında bir uygulamanın umursadığı tek şey ne kadarlık alana sahip olduğudur. Sahne yapılandırması, geometri geri çağrıları, iki basamaklı strateji, Info.plist kırmızı çizgileri ve test matrisiyle.

Resizability, bir uygulamanın penceresinin masaüstü penceresi gibi kenarından tutulup özgürce sürüklenerek herhangi bir boyuta getirilebilmesi demektir. Apple'ın bu değişimle birlikte verdiği tasarım düşüncesi tek cümleye sığar: bir uygulama artık hangi cihazda, hangi yönelimde, hangi ekran üzerinde çalıştığını umursamaz. Yalnızca o anda ne kadar alana sahip olduğunu umursar. Sizin tanımladığınız iki davranıştır: içerik alan genişken nasıl diziliyor, alan darksa nasıl diziliyor. Sistem bu mantığı tüm cihazlara, tüm pencere boyutlarına ve tüm katlama duruşlarına uygular.

Bu sıradan bir API güncellemesi değil. iOS'un doğuşundan bu yana yerleşim paradigmasında şerit değiştirmedir. Bu yazı, resizability'nin tasarım düşüncesini beş ilkeye ayırır, her birini UIKit ve SwiftUI koduna indirir ve olduğu gibi uygulayabileceğiniz bir geçiş yol haritası ve bir test matrisiyle biter.

Metindeki imzalar Xcode 27.1'in iOS 27.1 SDK'sına göre kontrol edildi. Davranış Apple'ın dokümantasyonunu ve WWDC oturumlarını izler; kaynaklar sonunda listelenmiştir. Gövde bir aktarım ve teknik düzenlemedir, belirli bir sayfanın tercümesi değildir.

1. iOS 26'dan 27'ye: yeniden boyutlandırma nasıl varsayılan oldu

Tasarım düşüncesinden önce zaman çizgisi. "Eski yöntemin" neden yeterli olmadığını açıklar.

Aşama Ne oldu Sizin için ne anlama geliyor
iPadOS 15 Split View / Slide Over / Stage Manager iPad tam ekran dışı boyutlarla tanışır
iPadOS 26 iPad özgür pencere çağına giriyor "iPad = regular" varsayımı sarsılmaya başlar
iOS 26 SDK UIRequiresFullScreen kullanımdan kaldırıldı Tam ekran tuşuyla boyutlandırmadan çıkılamıyor
iOS 26 SDK iPhone uygulamaları iPad'de ve Mac'te yansımada da boyutlanıyor "iPhone'da çalışıyor" artık compact demek değil
iOS 27 Güncel SDK ile yapılan yapılar için UIScene yaşam döngüsü zorunlu Sahneler temel haline gelir
iOS 27 Sekme çubuğu, araç çubukları: sistem bileşenleri her en boy oranına uyum sağlar Sistem bileşenleri ağır işi üstlenir

İpliği tek cümlede: pencere boyutu "sıralı değer"den "sürekli değer"e geçti. Eskiden uygulamanız 375, 393, 414, 768, 1024 ile karşı karşıyaydı. Şimdi bir parmak pencere kenarından tutup bir kez sürüklüyor: genişlik 320 ile ekran sınırı arasındaki herhangi bir sayı olabilir. Ayrık basamaklara göre yazılmış yerleşim, sürekli değerin önünde kesinlikle kırılır.

2. İlke bir: "cihaz düşüncesi"nden "alan düşüncesi"ne

Eski yerleşim bilgisinin çoğu cihaz düşüncesi üzerinde durur: bu bir iPhone, yatay duruyor, öyleyse böyle dizilir; bu bir iPad, öyleyse ikiye bölünür. Resizability bu düşünceyi tümüyle değiştirmeyi ister.

Cihaz düşüncesi (eski) Alan düşüncesi (yeni)
Karar ölçütü Cihaz türü, yönelim, ekran boyutu Geçerli kabın kullanılabilir alanı
Yerleşim sayısı Cihaz başına bir sürüm Tüm alanları kaplayan tek bir kural kümesi
Yeni donanım Kod değişikliği ve yeni bir sürüm gerektirebilir Kendiliğinden uygulanır, sıfır değişiklik
Katlama duruşları Duruş başına bir arayüz daha Genişlikle birlikte uzayıp küçülen tek bir arayüz
Kod kokusu if idiom == .pad, isLandscape horizontalSizeClass, kab genişliği

Alan düşüncesinin en sade ifadesi WWDC'den gelir: her platform için, her pencere boyutu için ayrı ayrı tasarım yapmazsınız. İeriğin "alan fazlaken nasıl, alan azken nasıl davrandığını" bir kez tanımlarsınız. Sistem bu mantığı tüm en boy oranlarına uygular. Ekranı çevirmek yalnızca bu mantığın bir tetikleyicisidir; bir pencereyi sürüklemek, Split View'e girmek veya bir ekranı açmakla aynı türdendir — hepsi tek bir noktada birleşir: kullanılabilir alan değişti.

3. İlke iki: boyut sınıfları yeni ortak dildir

Cihaz düşüncesi çekildiğinde sopayı kim devralır? Boyut sınıfı. Alanın çatı tarafından yapılan nitelikli yargısıdır: iki eksen, her eksende iki sözcük — compact dar olduğunu, regular geniş olduğunu belirtir.

  • Yatay eksen sola ve sağa bakar: compact'ta içerik tek kolona yığılmalıdır; kolonlar, yan yana dizim ve kenar çubuğu ancak regular olduğunda dürüst olur.

  • Düşey eksen yukarı ve aşağı bakar: compact'ta düşey chrome (sekme çubuğu, araç çubuğu) artık sığmaz ve sistem yatay sekme çubuğunu düşey yapar. regular'da üst ve alt çubuklar bir arada yaşar.

SwiftUI'de okuması doğrudan:

@Environment(\.horizontalSizeClass) private var hSize  // UserInterfaceSizeClass?
@Environment(\.verticalSizeClass) private var vSize

if hSize == .regular {
    // Solda ve sağda yer var: kolonlar / kenar çubuğu / iki sıra
} else {
    // Solda ve sağda dar: tek kolon yığını
}

UIKit'te traitCollection.horizontalSizeClass aynı görevi yüklenir ve registerForTraitChanges değişikliklere tam abone olunmasını sağlar.

Bu yazının en önemli tablosu geliyor — boyut sınıfları cihaz ve yönelimle birebir ilişkili değildir:

Sahne Yatay Düşey Not
iPhone dikey compact regular Tüm uygulamanın varsayılan biçimi
iPhone yatay compact compact Yükseklik yaklaşık 320 pt, sekme çubuğu düşey olur
iPhone penceresi büyütüldü (iOS 26+) regular regular Çalışma anında değişir, başlangıçta sabitlenmez
iPad tam ekran regular regular Genişlik yaklaşık 1024 pt
iPad yarım Split View regular regular Genişlik yalnızca yaklaşık 507 pt, yine regular
iPad Slide Over compact compact iPad üzerinde bir compact biçimi
Duo dış ekran compact compact Dış ekran genişliği yaklaşık 466 pt
Duo açılmış iç ekran regular compact Katlama durumuyla çalışma anında değişir

Bu tabloyu üç kez okuyun ve sezgiye aykırı iki sonuç ortaya çıkar: "iPhone'da çalışıyor" artık compact demek değil (büyütülmüş pencere regular'dır), ve "iPad'de çalışıyor" artık regular demek değil (Slide Over compact'tır). Ne cihaz türü ne de yönelim "şimdi hangi yerleşimi kullanmalıyım" sorusunu yanıtlar. Yalnızca çalışma anında boyut sınıfına sormak yanıtlar.

Tablo eski bir inancı da düzeltir: cihazı çevirmek "cihaz değişti" demek değildir. Çevirmek (H, V) çiftini (compact, regular)dan (compact, compact)a çevirir ve sınırları bir kez değiştirir. Yerleşim kodunuzun yapısı kımıldamaz; kıpırdayan yalnızca girdidir. "Yönelim"in yerleşim kavramı olduğu dönemde o hep bir yedek değişkendi. Yedek kalmadı. Yalnızca alan kaldı.

Boyut sınıfı uçuruğu: neden ikinci bir basamak gerekir

Boyut sınıfları ikilidir ve "yalan söyleyecek" kadar kabadır. Uçuruğa bakın: tam ekran iPad 1024 pt ile yarım Split View 507 pt ikisi de (regular, regular)dır — ama birine kenar çubuğu sığar, ötekine sığmaz. İki sözcük derece sorularını yanıtlayamaz: kaç kolon, ne kadar büyük, genişlik sınırlanacak mı?

Olak biçim bu nedenle iki basamaklı bir bayraktır: boyut sınıfları yön sorusunu (tek kolon mu bölünmüş mü) yanıtlar, mühendislik stratejisi derece sorusunu yanıtlar (kaç kolon, öne çıkan boyutu, okuma genişliği). İkinci basamak tipik olarak ölçülen kab genişliğine göre kademelenir: geniş ekranda metni rahat bir satır uzunluğuna sınırlar veya kolon sayısını içeriğin asgari boyutundan çıkarır. iOS 17'den itibaren SwiftUI onGeometryChange ile kab boyutunu doğrudan ölçip karara katabilir; GeometryReadera dönmek gerekmez.

4. İlke üç: işlevsellik boyutla değişmez, yalnızca "görünür miktar" değişir

Bu, Human Interface Guidelines'ın gözden kaçırması kolay ama gözden kaçırılmaması gereken bir ilkesidir: boyut sınıfı değiştiğinde işlevsellik kümesi aynı kalır. Değişen "bir seferde ne kadar göründüğü"dür.

Geniş ekranda sekme çubuğu kenar çubuğuna açılır ve ikinci düzey hedefleri ortaya çıkarır. Dar pencerede düşük öncelikli araçlar taşma menüsüne gider ve tek dokunuşla ulaşılabilir kalır. Saklamak yeniden düzenlemektir, silmek değil. Bir eylem geniş yerleşimde var olup darında iz bırakmadan kayboluyorsa bu uyum değil, eksik bir işlevdir. Aynı şekilde dikey ile yatay arasında asla "bu ekran yalnızca bir yönelimde tam çalışır" diye bir şey olmamalıdır: dikeyde işleyen şey yatayda da baştan sona işlemelidir.

Ürünü tasarlayana örtük istek şudur: bilgi mimarisinde her elemana bir öncelik yazın. Paylaşmak ve birincil eylemler yüksek önceliklidir ve her boyutta yerini korur. Kaydetmek ve ikincil ayarlar düşük önceliklidir: genişken yerinde, darken taşma menüsünde. Sistem bileşenlerinin Visibility Priority mekanizması tam olarak bunu yapar.

5. İlke dört: min / max boyutlar çakışmayı önler, boyutlandırmayı reddetmez

UIKit bir sahneye asgari ve azami boyut bildirmesine izin verir. Ama anlam net olmalıdır: bu iki değer, küçük boyutlarda elemanların birbirini örtmesini ve büyük boyutlarda dağılmasını önlemek için vardır. Kullanıcının sürüklemesine izin verilmeden önce aşması gereken bir engel değildir. Bir pencere her boyuta sürüklenebildiğinden beri sorumluluğunuz, her boyutta içeriği en azından kullanılabilir, okunabilir ve çakışmasız tutmaktır. Belirli bir boyut kaçınılmaz olarak kırıyorsa, asgari boyutunuz fazla açgözlüydü ya da yerleşim henüz gerçekten uyumlu değildir.

Sahne bağlanırken bildirilir:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
           options: UIScene.ConnectionOptions) {
    guard let windowScene = scene as? UIWindowScene else { return }

    // Alt sınır: bunun altında elemanlar çakışmaya başlar.
    // Üst sınır: bunun üstünde yerleşim gevşer.
    windowScene.sizeRestrictions?.minimumSize = CGSize(width: 320, height: 480)
}

Yanında gelen eski borç: UIRequiresFullScreen kullanımdan kaldırıldı ve onu koruyan uygulama boyutlandırmadan dışlanır: yeni ekran boyutlarını kendiliğinden elden çıkarır. iOS 26 SDK'sından beri uygulamaların yeni ekranlar için kod değiştirmesine ya da yeniden göndermesine gerek yoktur; sistem kendiliğinden uyum sağlar — kapıyı kendiniz kilitlemediğiniz sürece.

6. İlke beş: sistem bileşenlerinin çalışmasına izin verin

Resizability çağında en az zahmetli strateji, yeniden düzenlemeyi sistem bileşenlerine devretmektir. Keyfi en boy oranlarına olan davranışları, elden yazılmış herhangi bir yerleşimden sağlamdır:

  • Sekme çubukları ve araç çubukları: pencere genişledikçe sekme simgeleri etiketleriyle aynı satırda kalır ve çubuğu sade tutar; daraldıkça düşük öncelikli araçlar taşma menüsüne akar. Bir haber uygulamasında "Paylaş" her boyutta sabitlenebilir, "Sonra oku" yalnızca darlıkta taşar; Visibility Priority ile bildirilir, tek satır yerleşim kodu gerekmez.

  • Kenar çubukları: iPadOS 26'dan beri iPhone uygulamaları da alan izin verdikçe kenar çubuğu yerleşimini seçebilir; sidebar.isAvailable ile korunur.

  • NavigationSplitView: iOS 26'dan beri kolonlar alana göre görünür ve kaybolur; görünürlüğünü elle yönetmek artık gerekmez.

  • Liquid Glass sistem malzemeleri: iOS 27'de geliştirilmiş dağılım ve kenar ayrımıyla; yeniden derlemeden miras alınır.

Kendi arayüzünüzün burada tek bir görevi vardır: bu tuğlalarla dövüşmemek. Elle çizilen üst çubuklar, pencerenin sol üst köşesindeki kapat ve küçült denetimlerinden kaçınmalıdır (yatay köşe uyumlu yerleşim kılavuzuyla). Asla sekme çubuğunun her zaman altta, araç çubuğunun her zaman üstte olduğunu varsaymayın — biçimlerinin kendisi alanla değişir.

7. UIKit'te uygulama: sahne yapılandırması ve geometri yanıtı

Sahneler resizability'nin temelidir: her sahne kendi arayüz ve durum örneğini bağımsız yönetir ve "bu arayüz nerede, ne kadar büyüklükte" bağlamını sağlar. iOS 27'den beri güncel SDK ile yapılan yapılar UIScene yaşam döngüsünü benimsemelidir: bu seçime bağlı değildir.

Olduğu gibi kopyalanabilecek bir sahne delegesi iskeleti:

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
               options: UIScene.ConnectionOptions) {
        guard let windowScene = scene as? UIWindowScene else { return }

        // 1) Boyut yeteneğini bildir: çakışmayı önle, boyutlandırmayı reddetme
        windowScene.sizeRestrictions?.minimumSize = CGSize(width: 320, height: 480)

        // 2) Pencereyi sahneye as; asla UIWindow(frame: UIScreen.main.bounds) değil
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = AdaptiveRootController()
        self.window = window
        window.makeKeyAndVisible()
    }

    // 3) Geometri değişim geri çağrısı: sürükleme, Split View, açma, dış ekran
    func windowScene(_ windowScene: UIWindowScene,
                     didUpdateEffectiveGeometry previous: UIWindowScene.Geometry) {
        let geometry = windowScene.effectiveGeometry
        let size = geometry.coordinateSpace.bounds.size

        // isInteractivelyResizing, kullanıcının hâlâ kenarı tuttuğu anlamına gelir.
        // Ağır iş (kaynak yeniden yapımı, grafik yeniden hesabı) hareket
        // bittiğinde bir kez yapılır: her ara boyut için değil.
        if !geometry.isInteractivelyResizing,
           size != previous.coordinateSpace.bounds.size {
            AssetStore.shared.rebuild(for: size)
        }
    }

    // 4) iPadOS 26+ pencere denetimlerinin (kapat / küçült) stil tercihi
    func preferredWindowingControlStyle(for scene: UIWindowScene)
        -> UIWindowScene.WindowingControlStyle {
        .unified
    }
}

Açılması gereken üç nokta var:

isInteractivelyResizing, sürükleme performansının cankurtaranıdır. Kullanıcı sürüklerken sistem geometriyi sürekli bildirir. Bir oyun ya da uygulama her ara boyut için render kaynaklarını yeniden kuruyorsa kare hızı yerinde çöker. Standart duruş: sürükleme sırasında yalnızca hafif iş (kısıtlar, yazı boyutları), bıraktıktan sonra bir kez ağır iş.

Ekranı ve boyutu asla UIScreen.main üzerinden almayın. Yansımada ve dış ekranda ana ekran yanlış yanıttır. Doğru kaynaklar view.window?.windowScene?.screen, sahnenin effectiveGeometry'si veya görünümün yerel view.bounds'udur.

Pencere denetimlerinden kaçınmak. iPadOS 26'dan beri sahnenin sol üst köşesinde kapat ve küçült denetimleri bulunur. Elle çizilen üst çubuklar containerView.layoutGuide(for: .margins(cornerAdaptation: .horizontal))'ya bağlanmalıdır, yoksa ilk düğmeniz dokunulamaz hale gelir.

8. Görünüm katmanı: üç eski deseni silmek

Uyumlu UIKit görünüm kodu özünde "üç değiştirme"dir:

Silinecek Değiştirilecek Neden
UIScreen.main.bounds view.bounds / effectiveGeometry / windowScene?.screen Split View ve yansımada ana ekran sizin pencereniz değildir
userInterfaceIdiom == .pad dalları traitCollection.horizontalSizeClass Cihaz türü yerleşim anlamı taşımaz
interfaceOrientation dalları Boyut sınıfı + yerel sınırlar Yönelim yerleşimin sonucudur, nedeni değil

Değişimden sonra yerleşimi trait değişimi sürer:

class AdaptiveRootController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Boyut sınıfı değişince yeniden düzenle; kayıt ayrıca otomatik
        // izlemenin görmediği önbellek geçersizliğini de karşılar
        registerForTraitChanges([UITraitHorizontalSizeClass.self,
                                 UITraitVerticalSizeClass.self]) { (vc: Self, _) in
            vc.applyLayout()
        }
    }

    private func applyLayout() {
        switch (traitCollection.horizontalSizeClass, traitCollection.verticalSizeClass) {
        case (.regular, _):   useSidebarLayout()
        case (.compact, _):   useStackedLayout()
        default:              useStackedLayout()
        }
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        // Yargı boyut sınıfından ince olduğunda: yerel kullanılabilir boyut
        fineTune(for: view.bounds.size)
    }
}

viewDidLayoutSubviews / layoutSubviews'in sürekli etkili olduğuna dikkat: boyut sınıfı değişimi "yapısal yeniden düzenlemeyi", sınır değişimi "ince ayarı" tetikler. onAppear / viewDidLoad içinde boyutu bir kez okuyup saklamak, boyutlandırma başlar başlamaz ilk eskimiş değerleri üretir.

9. SwiftUI'de uygulama: çoğunlukla otomatik, kilit noktalarda destekli

SwiftUI ile yazılan uygulamalar resizability'de öndedir: Xcode 27 ile yeniden derlendiğinde pencere boyutlandırma desteği kendiliğinden gelir, benimsenecek yeni API yoktur ve yeni Liquid Glass malzemeleri yolda miras alınır. Ama "otomatik", "denetimsiz" demek değildir. SwiftUI tarafındaki araç kutusu:

  • @Environment(\.horizontalSizeClass) / verticalSizeClass: UIKit trait'inin karşılığıdır, yön sorularını yanıtlar.

  • onGeometryChange(for:of:action:): kabı ölçer, derece sorularını yanıtlar. GeometryReader'ın açgözlü yer tutuşunu tetiklemeden okur ve yalnızca türetilmiş değer gerçekten değiştiğinde eylemi çağırır — sürükleme sırasındaki ara boyutlar için doğal bir süzgeç.

  • ViewThatFits: "sığan ilkini al" bildirimsel yazımı, içerik genişliğe göre dizim değiştirdiğinde uygundur.

  • containerRelativeFrame(): mutlak puan yerine kab oranına göre boyutlandırır; sistem arayüzünün altına uzanması gereken alanlar için çok işe yarar.

  • NavigationSplitView: iOS 26'dan beri kolon genişliği ve görünürlüğü kendiliğinden uyum sağlar; üzerine elle kolon yönetimi sarmayın.

  • .windowResizability(.contentMinSize): SwiftUI'nin asgari sahne boyutunu bildirme girişidir, sizeRestrictions?.minimumSize karşılığıdır.

Tipik iki basamaklı bir bayrak:

struct DashboardView: View {
    @Environment(\.horizontalSizeClass) private var hSize
    @State private var columnCount = 1

    var body: some View {
        ScrollView {
            MetricGrid(columns: columnCount)
        }
        // Basamak bir: boyut sınıfı tek kolon mu bölünmüş mü karar verir
        .onChange(of: hSize) { _, new in
            usesSidebar = (new == .regular)
        }
        // Basamak iki: ölçülen genişlik kolon sayısını belirler,
        // ikisi de "regular" olan 507 ve 1024'i kapsar
        .onGeometryChange(for: CGFloat.self) { $0.size.width } action: { _, width in
            columnCount = AdaptiveWindowLayoutPolicy.tier(for: width).columns
        }
    }
}

10. Info.plist ve Launch Screen'de kırmızı çizgiler

Proje yapılandırmasında iki kırmızı çizgi yaşar. Birini şaşırırsanız patlaması gönderim anına denk gelir:

  1. UIRequiresFullScreen ele alınmalıdır. Kullanımdan kaldırıldı ve onu koruyan uygulama boyutlandırmadan dışlanır. Silin; gerçek bir geriye dönük uyumluluk ihtiyacı taşıyorsa, anahtarın hangi sürümden itibaren yok sayılacağını bildirmek için UIRequiresFullScreenIgnoredStartingWithVersion kullanın. Oyunlar bu sonuçla ayrık boyutlandırmaya girer: her tamamlanan sürüklemeyi, boyuta uyan yeni bir ekran yapılandırmasına çevirir ve tam kalite renderini korur.

  2. Launch Screen zorunludur. iOS 26 SDK'sından beri yapılandırılmış Launch Screen'i olmayan uygulamalar App Store gönderimini geçemez (TN3208). Bir SwiftUI projesinde bu genellikle asgari bir başlangıç ekranı yapılandırması eklemek demektir: çıplak koşmaya devam etmek değil.

11. Anti-desen hızlı başvuru

Koda dokunmadan önce kod tabanını bu desenlerin ince eleğinden geçirin. Her çıkış ödenmesi gereken borçtur:

Anti-desen Neden kırılır Değiştirilecek
UIScreen.main.bounds Split View / yansımada sizin pencereniz değil Yerel view.bounds veya sahne geometrisi
UIDevice.current.userInterfaceIdiom dalları Cihaz türünün yerleşim anlamı yoktur horizontalSizeClass
interfaceOrientation / yönelim bildirimleri Cihaz duruşunu bildirir, pencere biçimini bildirmez Boyut sınıfı + yerel sınırlar
size.width > 600 gibi elden eşikler Trait anlamını baypas eder, Split View ara durumlarını kaçırır Mühendislik kademe stratejisi + onGeometryChange
onAppear'da bir kez okumak Boyutlandırma süreklidir; önbellek anında bayatlar Trait / geometri geri çağrıları
Yalnızca iPad için geniş yerleşim Slide Over'daki iPad telefon gibi davranır Geniş ve dar mantık ikisi de alanla tetiklenir
Harita / öne çıkan alan için sabit .frame(height: 480) Kısa pencerelerde metin ilk ekranın dışına kayar Kaba göreceli veya uyumlu yükseklik

12. Geçiş yol haritası

Risk ve getiriye göre sıralanmış dört adım:

Aşama 1 · Mayını sökmek (önce, gönderimi engeller): UIRequiresFullScreen silmek, Launch Screen eklemek, UIScene yaşam döngüsünün kullanımda olduğunu doğrulamak. Bu üç nokta tasarım kalitesinden bağımsız sert kapılardır; birini bırakmak doğrudan yapıda ya da incelemede tıkar.

Aşama 2 · Anti-desenleri temizlemek: 11. bölümün tablosuyla UIScreen.main, idiom / yönelim dalları ve elden genişlik eşiklerini tüm kod tabanında değiştirmek. Hedef "çalışıyor" değil, yerleşimin girdisini alan anlamı üzerinde birleştirmektir.

Aşama 3 · İki basamağı kurmak: içerik odaklı ekranlar için "boyut sınıfı yönü, ölçülen genişlik dereceyi belirler" stratejisini kurmak ve her çıplak eşiği tek yerde toplamak. Geniş ekranda metin genişliğini sınırlamaya dikkat: 85 karakteri aşan satır okunabilirlik hatasıdır.

Aşama 4 · Testi sistematikleştirmek: 13. bölümün matrisini boyut boyut dolaşmak ve sonuçları gerileme noktaları olarak dondurmak.

13. Test matrisi

Resizability testleri cihaz listesiyle değil, alan biçimleriyle organize edilir. Her biçim şunu yanıtlamalıdır: işlevsellik tam mı, içerik kırpılıyor mu, chrome dokunulabilir mi?

Alan biçimi Doğrulanacak
En dar kullanılabilir genişlik (minimumSize yakını) Eleman çakışması, birincil düğmeler dokunulabilir mi
Standart telefon genişliği Varsayılan yerleşimin taban çizgisi
Telefon yatay Düşey compact'ta sekme çubuğu düşey, ilk ekran eksiksiz
Telefon penceresi regular'a büyütüldü Kolonlar devralıyor mu, durum korunuyor mu
Yarım Split View / Slide Over Aynı iPad üzerinde iki alan davranışı
Aşırı geniş-nesel ve yüksek-dar oranlar Arka plan uzantısı tutuyor mu, içerik yırtılmıyor mu
Duo dış ve açılmış iç ekran Katlama geçişinde yerleşim ve durum sürekli mi
iPhone yansıması / dış ekran Ekran ve boyut sorguları doğru mu

Araç tarafında, Xcode 27'nin Device Hub'ı ve Önizlemeleri pencere yeniden boyutlandırma modu sunar; kenardan çekmek boyutu sürekli değiştirir. Yansıma ve dış ekranlar gerçek donanımda doğrulanır.

14. Sık sorulan sorular

iPhone uygulamam neden aniden daha büyük bir pencereye sürüklenebiliyor?

Bu bir hata değil: iOS 26 SDK'sından beri yeni davranış. iPad'de ve Mac'te iPhone yansımasında çalışan iPhone uygulamalarının özgürce boyutlanabilir pencereleri vardır. Karşılık gelen yerleşim sinyali, yatay boyut sınıfının compact'tan regular'a dönmesidir. Eski if idiom == .phone kodu böyle pencerelerde yanlış yerleşim üretir. Boyut sınıfına sorun.

Boyut sınıfları yeterli mi? Neden genişliği de ölçelim?

Yeterli değil ve uçuruk gerçektir. Tam ekran iPad ile yarım Split View ikisi de (regular, regular)dır, ama genişlikleri iki katı fark eder: birine kenar çubuğu sığar, ötekine sığmaz. Boyut sınıfı yönü (tek kolon / bölünmüş), ölçülen genişlik dereceyi (kaç kolon / ne kadar) belirler. İkisi bir bayraktır, bir seçim değil.

minimumSize bildirirsem kullanıcılar daha küçük sürükleyemez mi?

minimumSize, içeriğinizin karmakarışık olmaya başladığı alt sınırdır; kullanıcılar bu sınırın ötesine sürükleyemez. Bu bir çakışma önleme mekanizmasıdır, boyutlandırmaya karşı bir işlev kilidi değil. Borçlu olduğunuz, minimumSize ile maximumSize arasındaki her boyutta kullanılabilirliktir. Bir boyut başarısız oluyorsa uyum tamamlanmamıştır: asgari değeri artırmak bir sebep değildir.

UIRequiresFullScreen'i silersem ne olur?

Uygulama pencere boyutlandırmaya girer, iOS 26+'tan beri beklenen varsayılan budur. Geriye dönük uyumluluk için yok saymaya başlanacak sürümü bildirmek üzere UIRequiresFullScreenIgnoredStartingWithVersion kullanabilirsiniz; oyunlar ayrık boyutlandırmaya girer ve her sürüklemeyi uyan bir ekran yapılandırmasına çevirir, bu render kalitesini daha iyi korur.

Bir SwiftUI uygulamasının gerçekten yapması gereken ne?

Yeniden derlemek ve boyutlandırma desteği oradadır; benimsenecek yeni API yoktur. Onun yerine denetleyin: UIScreen çağı varsayımlarına dayanan kod; yalnızca boyut sınıfını kullanıp ölçüm desteği olmayan boyut yargıları; aşırı oranlarda yırtılan sabit çerçeveli bileşenler. Çatı makroyu üstlenir. Yırtılan bileşen genellikle kendinizin çivilediğidir.

Kaynaklar ve daha fazla okuma

Resmi kaynaklar: WWDC25 oturum 282 "Make your UIKit app more flexible", WWDC26 oturum 278 "Modernize your UIKit app", Human Interface Guidelines'ın Layout ve Designing for iPhone Duo bölümleri, UISceneSizeRestrictions ve UIWindowScene.Geometry dokümantasyonu, TN3192: kullanımdan kaldırılan UIRequiresFullScreen anahtarından geçiş ve TN3208: Launch Screen gereksinimleri teknik notları.

Sitede daha fazla okuma: aynı düşüncenin somut bir cihazda baştan sona nasıl yere indiğini görmek için iPhone Duo için arayüz: yerleşimden koda yazısını okuyun. Diğer yüz için — verilerin de alanla birlikte küçülmesi gerektiğini — kişisel taban çizgisi rehberine bakın. Ürün ve uyumla ilgili diğer sorular sık sorulan sorularda yer alıyor.

Okumaya devam

Bu fikirleri Stress HRV’te deneyin

App Store'dan indir

Bu notlar kişisel wellness için ürün düşüncesi paylaşır. Tıbbi tavsiye değildir.