Adaptive Layout: temel kavramlar, boyut sınıfları ve niteleyiciler

Yazar: IT Sectr Yayınlanma: 2026-02-26 Okuma süresi: 10 dk

Adaptive Layout, uygulamanın farklı cihaz türleri ve ekran yönleri için farklı düzenler kullandığı bir arayüz düzeni yaklaşımıdır. Responsive design'ın aksine, adaptive layout kesme noktalarında önceden hazırlanmış düzenler arasında geçiş yapar. Bu makale iOS'ta Size Classes ve UITraitCollection'ı, Android'de sw600dp/layout-w600dp niteleyicilerini ve pratik örnekleri ele almaktadır.

Önemli Noktalar

  • Adaptive Layout — ekran boyutu, yön ve cihaz türüne göre düzenlerin ayrık geçişi
  • Size Classes iOS'ta alanı yatay ve dikey olarak Compact veya Regular olarak sınıflandırır
  • UITraitCollection — iOS ortam özellikleri kabı (boyut, ölçek, force touch, renk gamı)
  • sw600dp — Tabletler (7\" ve üzeri) için Android minimum genişlik niteleyicisi
  • layout-w600dp — Mevcut yönde yeterli alan olduğunda etkinleşen kullanılabilir genişlik niteleyicisi

Adaptive Layout Nedir?

Adaptive Layout, geliştiricinin her cihaz türü için ayrı düzenler oluşturduğu ve ekran özelliklerine göre aralarında geçiş yaptığı bir UI stratejisidir. Öğelerin sorunsuzca aktığı responsive design'ın aksine, adaptive layout ayrık geçiş kullanır: telefon — bir düzen, tablet — başka bir düzen, masaüstü — üçüncü bir düzen.

Apple, iOS 8'de (2014) evrensel uygulamalarla (hem iPhone hem iPad'de çalışan ikili dosyalar) birlikte Size Classes'ı tanıttı. Google, Android 3.2'de (2011) smallestWidth niteleyicisini (swdp) sundu. Her iki mekanizma da aynı sorunu çözer: geliştiriciye kod tekrarı olmadan farklı ekranlar için farklı UI'ler oluşturma aracı vermek.

Modern Apple HIG ve Google Material Design yönergeleri, birden fazla ekran boyutunu destekleyen uygulamalar için adaptive layout'un gerekli olduğu konusunda hemfikirdir. Google Play, tablet uyarlamasının olmamasını bir eksiklik olarak işaretler. App Store'un resmi bir gereksinimi yoktur, ancak iPad kullanıcıları gerilmiş bir iPhone uygulaması değil, yerel bir deneyim bekler.

iOS'ta Size Classes ve UITraitCollection

Size Classes, her eksende kullanılabilir alanı Compact (Dar) veya Regular (Normal) olarak tanımlayan bir iOS özelliğidir. UITraitCollection, görünüm hiyerarşisi boyunca ortam özelliklerini ileten bir iOS sistemidir: boyut, ekran ölçeği, force touch yeteneği, renk gamı (açık/koyu), erişilebilirlik ayarları.

Cihaz / YönYatayDikey
iPhone dikey (tüm modeller)CompactRegular
iPhone Plus/Pro Max yatayRegularCompact
iPhone SE / mini yatayCompactCompact
iPad dikeyRegularRegular
iPad yatayRegularRegular
iPad Split View (1/3 ekran)CompactRegular

UITraitCollection sistem tarafından oluşturulur ve UIApplication'dan UIWindow aracılığıyla her UIView'e iletilir. Yön veya pencere boyutu (Split View) değiştiğinde, sistem yeni bir UITraitCollection oluşturur ve traitCollectionDidChange'i çağırır. SwiftUI'da değişiklikler Environment Values aracılığıyla izlenir ve görünüm otomatik olarak yeniden çizilir.

Swift'te Uyarlanabilir Düzen Örneği

UIKit'te UITraitCollection aracılığıyla uyarlama, trait collection değişikliklerine abone olarak ve düzeni yeniden oluşturarak uygulanır. Aşağıdaki örnek, iPhone için dikey yığın ile iPad için bölünmüş düzen arasında geçiş yapan bir denetleyiciyi göstermektedir.

swift
// Size Classes ile Uyarlanabilir Denetleyici
import UIKit

final class AdaptiveViewController: UIViewController {

    private let compactStack = UIStackView()
    private let regularStack = UIStackView()
    private let sidebar = UIView()
    private let content = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
        updateLayout(for: traitCollection)
    }

    override func traitCollectionDidChange(
        _ previousTraitCollection: UITraitCollection?
    ) {
        super.traitCollectionDidChange(previousTraitCollection)
        if traitCollection.horizontalSizeClass
            != previousTraitCollection?.horizontalSizeClass {
            updateLayout(for: traitCollection)
        }
    }

    private func updateLayout(for traits: UITraitCollection) {
        if traits.horizontalSizeClass == .regular {
            showRegularLayout() // iPad: kenar çubuğu + içerik
        } else {
            showCompactLayout() // iPhone: sekme çubuğu + push
        }
    }

    private func showRegularLayout() {
        view.subviews.forEach { $0.removeFromSuperview() }
        regularStack.addArrangedSubview(sidebar)
        regularStack.addArrangedSubview(content)
        regularStack.frame = view.bounds
        regularStack.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(regularStack)
    }

    private func showCompactLayout() {
        view.subviews.forEach { $0.removeFromSuperview() }
        compactStack.addArrangedSubview(content)
        compactStack.frame = view.bounds
        compactStack.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(compactStack)
    }

    private func setupViews() {
        sidebar.backgroundColor = .systemGray6
        content.backgroundColor = .systemBackground
        compactStack.axis = .vertical
        regularStack.axis = .horizontal
    }
}

traitCollectionDidChange yöntemi herhangi bir özellik değişikliğinde çağrılır, ancak yalnızca düzen değişikliği için en önemli gösterge olan horizontalSizeClass'ı kontrol ederiz. iOS 17+'da, değişikliklere abone olmadan reaktif güncellemeler için UIViewController.horizontalSizeClass'ın hesaplanan özellik olarak kullanılması önerilir.

Android Niteleyicileri: sw600dp ve w600dp

Android iki ana genişlik niteleyicisi sağlar: swdp (smallestWidth) ve wdp (available width). Fark kritiktir: sw, yönden bağımsız minimum ekran genişliğidir, w ise mevcut yönü dikkate alan kullanılabilir genişliktir. sw, düzenin fiziksel olarak belirtilen minimum genişliğe sahip bir cihaz için yüklenmesini sağlar. w, dönüşe yanıt verir — yatay modda, dikeyde genişlik 360 dp olsa bile w600dp etkinleşebilir.

NiteleyiciKoşulCihaz Örneği
layout-sw600dpMinimum genişlik ≥ 600 dpiPad (768 dp), Pixel C (900 dp)
layout-w600dpMevcut genişlik ≥ 600 dpSplit View'da iPad (600 dp), yatay modda telefon
layout-landYatay yönYatay döndürülmüş herhangi bir cihaz
layout-sw720dpMinimum genişlik ≥ 720 dpiPad Pro (833 dp), Galaxy Tab S9 (800 dp)

Android'de kaynak hiyerarşisi: res/layout/activity_main.xml (telefon), res/layout-sw600dp/activity_main.xml (7\" tablet), res/layout-w600dp-land/activity_main.xml (yatay modda telefon). Android, mevcut cihaz yapılandırmasına uyan en spesifik niteleyiciyi seçer. Eşleşen dosya olmadığında, res/layout/ dizinindeki temel kaynak kullanılır.

Kotlin'de Uyarlanabilir Düzen Örneği

Modern Android geliştirme, kaynakları doğrudan okumak yerine pencere boyutunu belirlemek için Jetpack WindowManager kullanır. Bu, ekran boyutunun dinamik olarak değiştiği katlanabilir cihazlar için özellikle önemlidir (Galaxy Fold 6.2\"'den 7.6\"'ya açılır).

kotlin
// Jetpack WindowManager ile Uyarlama
import androidx.window.core.layout.WindowHeightSizeClass
import androidx.window.core.layout.WindowSizeClass
import androidx.window.core.layout.WindowWidthSizeClass

@OptIn(ExperimentalLayoutApi::class)
@Composable
fun AdaptiveScreen() {
    val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass

    FlowRow(
        verticalAlignment = Arrangement.Top,
        horizontalArrangement = when (windowSizeClass.windowWidthSizeClass) {
            WindowWidthSizeClass.EXPANDED -> Arrangement.SpaceEvenly
            else -> Arrangement.Start
        }
    ) {
        when (windowSizeClass.windowWidthSizeClass) {
            WindowWidthSizeClass.COMPACT -> {
                CompactContent()
            }
            WindowWidthSizeClass.MEDIUM -> {
                MediumContent()
            }
            WindowWidthSizeClass.EXPANDED -> {
                ExpandedContent()
            }
        }
    }
}

@Composable
private fun CompactContent() {
    Column(modifier = Modifier.padding(16.dp)) {
        Text("Telefon", style = MaterialTheme.typography.headlineSmall)
        ListContent()
    }
}

@Composable
private fun MediumContent() {
    Row(modifier = Modifier.padding(24.dp)) {
        NavigationRail { ... }
        Column { ListContent() }
    }
}

@Composable
private fun ExpandedContent() {
    Row(modifier = Modifier.padding(32.dp)) {
        PermanentNavigationDrawer { ... }
        Column {
            ListContent()
        }
        DetailPane()
    }
}

androidx.window kütüphanesindeki currentWindowAdaptiveInfo() bileşeni, arayüzü herhangi bir cihaza uyarlar: telefon, tablet, katlanabilir, ChromeOS. Genişlik sınıfları: COMPACT (0–600 dp), MEDIUM (600–840 dp), EXPANDED (>840 dp). Yükseklik sınıfları: COMPACT (0–480 dp), MEDIUM (480–900 dp), EXPANDED (>900 dp).

SwiftUI'da Adaptive Layout

SwiftUI, Size Classes'ı doğrudan kullanmadan uyarlanabilir düzen için yerleşik araçlar sağlar. AnyLayout, ViewThatFits ve GeometryReader, mevcut alana otomatik olarak uyum sağlayan arayüzler oluşturmayı sağlar.

swift
// AnyLayout ve ViewThatFits ile SwiftUI Uyarlaması
import SwiftUI

struct AdaptiveGrid: View {
    @Environment(\.horizontalSizeClass) private var hSizeClass

    var body: some View {
        let layout = hSizeClass == .regular
            ? AnyLayout(HStackLayout())
            : AnyLayout(VStackLayout())

        layout {
            Label("Favoriler", systemImage: "star")
            Label("Son", systemImage: "clock")
            Label("Ayarlar", systemImage: "gear")
        }
        .padding()
    }
}

// ViewThatFits — otomatik düzen seçimi
struct SmartLayout: View {
    var body: some View {
        ViewThatFits {
            HStack { // Öncelik 1: yatay
                CardView()
                CardView()
            }
            VStack { // Sığmazsa — dikey
                CardView()
                CardView()
            }
        }
    }
}

ViewThatFits, kırpma olmadan mevcut alana sığan ilk alt görünümü otomatik olarak seçen güçlü bir SwiftUI aracıdır. Bu, basit uyarlanabilir geçişler için Size Classes'ı açıkça kontrol etme ihtiyacını ortadan kaldırır. AnyLayout, görünüm gövdesinde if-else olmadan düzen türünü (HStack/VStack) değiştirmeyi sağlar.

Jetpack Compose'da Adaptive Layout

Jetpack Compose, uyarlanabilir düzen için WindowSizeClass'ı (Material 3 adaptive kütüphanesinden) ve BoxWithConstraints'ı kullanır. XML niteleyicilerinin aksine, Compose pencere boyutunu çalışma zamanında belirler ve yapılandırma değişikliklerinde UI'ı reaktif olarak yeniden oluşturur.

kotlin
// BoxWithConstraints ile Jetpack Compose uyarlanabilir
@Composable
fun AdaptiveList(items: List<String>) {
    BoxWithConstraints {
        val width = maxWidth

        if (width >= 600.dp) {
            // Tablet: iki sütun (list-detail)
            Row(modifier = Modifier.fillMaxSize()) {
                LazyColumn(modifier = Modifier.weight(1f)) {
                    items(items) { item ->
                        ListItem(text = item)
                    }
                }
                var selected by remember { mutableStateOf(items.first()) }
                DetailPanel(item = selected)
                    .weight(2f)
            }
        } else {
            // Telefon: gezinmeli tek sütun
            LazyColumn(modifier = Modifier.fillMaxSize()) {
                items(items) { item ->
                    ListItem(text = item, onClick = { navigateToDetail(item) })
                }
            }
        }
    }
}

@Composable
fun AdaptiveListMaterial3() {
    val windowClass = currentWindowAdaptiveInfo().windowSizeClass

    AdaptiveLayout(
        layout = windowClass.windowWidthSizeClass
    ) {
        when (windowClass.windowWidthSizeClass) {
            WindowWidthSizeClass.COMPACT -> {
                ListDetailScaffold(
                    isDetailOnly = false,
                    list = { ListPane() },
                    detail = { DetailPane() }
                )
            }
            else -> {
                ListDetailScaffold(
                    isDetailOnly = false,
                    list = { ListPane() },
                    detail = { DetailPane() }
                )
            }
        }
    }
}

Material 3 Adaptive Layouts, hazır bileşenler sağlar: ListDetailScaffold, SupportingPaneScaffold, NavigationSuiteScaffold. Bu bileşenler WindowWidthSizeClass'a otomatik olarak uyum sağlar — yığılmış (COMPACT) ve yan yana (MEDIUM/EXPANDED) arasında geçiş yapar. Geliştiricinin sadece bir desen seçmesi ve içerik panellerini iletmesi yeterlidir.

Sıkça Sorulan Sorular

sw600dp ve w600dp arasındaki fark nedir?

sw600dp (smallestWidth) — yönden bağımsız minimum ekran genişliği. 7\"+ tabletlerde her zaman etkinleşir. w600dp (available width) — mevcut yönü dikkate alan kullanılabilir genişlik. Genişliğin 600 dp'yi aşabileceği yatay moddaki telefonlarda etkinleşir.

iOS'ta UITraitCollection nedir?

UITraitCollection, ortam özelliklerini içeren bir iOS nesnesidir: size classes (yatay/dikey), ekran ölçeği, force touch yeteneği, kullanıcı arayüzü idiomu (iPhone/iPad), renk gamı, erişilebilirlik ayarları. UIApplication'dan görünüm hiyerarşisi boyunca iletilir ve yön veya pencere boyutu değiştiğinde değişir.

Bir uygulama katlanabilir cihazlara nasıl uyarlanır?

Jetpack WindowManager (Android) ve UIScreen nativeBounds + traitCollection (iOS) kullanın. Katlanabilir cihazlar açıldığında Size Class'ı değiştirir. Activity'yi yeniden başlatmadan pencere boyutu değişikliklerine reaktif abonelik ile kurallı düzenlere (list-detail, supporting pane) dayalı bir mimari önerilir.

iPad için ayrı storyboard'lar oluşturmam gerekir mi?

Hayır. Size Class kısıtlama varyasyonlarına sahip tek bir storyboard veya UIKit aracılığıyla programlı düzen kullanın. SwiftUI hiç storyboard gerektirmez. iPad için ayrı storyboard'lar çoğaltma yaratır ve bakımı karmaşıklaştırır — Size Classes aracılığıyla tek bir düzeni uyarlamak daha iyidir.

Material 3'te kurallı düzenler (canonical layouts) nedir?

Canonical layouts, Google'ın hazır uyarlanabilir düzen desenleridir: list-detail (liste + detay), supporting pane (içerik + eylem paneli), feed (kartlar). Her desen üç durumu (compact/medium/expanded) destekler ve Material 3 Adaptive kütüphanesinde ListDetailScaffold ve SupportingPaneScaffold aracılığıyla uygulanmıştır.

Özet

  • Adaptive Layout — farklı cihazlar için kesme noktalarında ayrık düzen geçişi
  • Size Classes iOS (Compact/Regular) iPhone, iPad ve Split View için düzeni tanımlar
  • UITraitCollection — görünüm hiyerarşisi boyunca ortam özelliklerini iletme mekanizması
  • sw600dp — 7\"+ tabletler için Android minimum genişlik niteleyicisi
  • w600dp — yatay döndürüldüğünde etkinleşen kullanılabilir genişlik niteleyicisi
  • Jetpack WindowManager WindowSizeClass sağlar (WindowWidthSizeClass: COMPACT/MEDIUM/EXPANDED)
  • Material 3 Adaptive — otomatik uyarlama ile hazır bileşenler (ListDetailScaffold)

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun