---
title: 'Düzen Sistemi'
source: 'https://academia.sh/tr/kurslar/swiftui/duzen-sistemi'
course: 'SwiftUI ile Arayüz'
language: tr
updated: '2026-10-21T05:03:14+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Düzen sisteminin üç adımını (öneri, seçim, yerleştirme) kaynak parçada okur'
    - 'Önerilen boyutu belirleyen ebeveyn değerinin çocuklara ebeveyn tetiği olarak indiğini ölçer'
    - 'Yazı boyutu tercihi gibi ortam değerinin ayrı bir tetik ürettiğini gösterir'
    - 'Boyut önerisinin ölçülen bir durum değeri olmadığını ve modelin onu ölçüm dışı bıraktığını ölçer'
---

# Düzen Sistemi

Önerilen boyutu belirleyen ebeveyn değerinin çocuklara ebeveyn tetiği olarak indiğinin, yazı boyutu tercihinin ortamdan okunduğunun ve boyut önerisinin ölçülen bir değer olmadığının ölçümü.

Önceki derste yığıtın aralık ve ekseni, sahibi olan ebeveynden çocuklara indi. Bu derste aynı inişi boyutlar için izliyoruz. Düzen sisteminde üst görünüm, çocuğuna ne kadar yer önerdiğini söyler; çocuk bu öneriden kendi boyutunu seçer; üst görünüm de çocuğu seçtiği boyutla yerleştirir. Önerinin kendisi bir ebeveyn kararıdır, ama bu kararı belirleyen bir değer çoğu zaman ebeveynin durumunda durur. Soru aynı kalır: **bu yeniden hesaplamayı ne tetikledi?** Bu derste bakılan tetik, **ebeveyn**.

```swift
// Invalidation.swift — bir degisikligin hangi gorunumu hangi kaynak yoluyla yeniden hesaplattigini siniflandirir
enum Storage {
    case state(owner: String)
    case model(object: String)
    case environment
}

struct ViewNode {
    let name: String
    let parent: String?
    let reads: Set<String>

    init(_ name: String, parent: String?, reads: Set<String>) {
        self.name = name
        self.parent = parent
        self.reads = reads
    }
}

struct Recompute {
    let view: String
    let cause: String
}

struct ViewTree {
    let nodes: [ViewNode]
    let storage: [String: Storage]

    func ancestors(of name: String) -> [String] {
        var found: [String] = []
        var current = nodes.first { $0.name == name }?.parent
        while let next = current {
            found.append(next)
            current = nodes.first { $0.name == next }?.parent
        }
        return found
    }

    func cause(of node: ViewNode, key: String) -> String {
        guard let kind = storage[key] else { return "olcum-disi" }
        switch kind {
        case .environment:
            return "ortam"
        case .model:
            return "gozlem"
        case .state(let owner):
            if owner == node.name { return "yerel" }
            if ancestors(of: node.name).contains(owner) { return "ebeveyn" }
            return "kural-disi"
        }
    }

    func change(_ label: String, key: String) -> [Recompute] {
        let hits = nodes.filter { $0.reads.contains(key) }
            .map { Recompute(view: $0.name, cause: cause(of: $0, key: key)) }
        let skipped = nodes.filter { !$0.reads.contains(key) }.map(\.name)
        let recomputed = hits.isEmpty ? "yok" : hits.map { "\($0.view) \($0.cause)" }.joined(separator: ", ")
        let rest = skipped.isEmpty ? "yok" : skipped.joined(separator: ",")
        print("\(label): \(key) degisti | yeniden \(recomputed) | atlanan \(rest)")
        return hits
    }
}

func countCauses(_ recomputes: [Recompute]) {
    for cause in ["yerel", "ebeveyn", "gozlem", "ortam"] {
        print("\(cause): \(recomputes.filter { $0.cause == cause }.count)")
    }
}
```

Çekirdek, açılış dersindekiyle aynıdır. Bu dersin ağacı bir özet panelidir: panelin kendisi, bir başlık, bir grafik ve bir not.

## Öneri, Seçim, Yerleştirme

Düzen üç adımda ilerler. Ebeveyn çocuğa bir boyut önerir; çocuk bu öneriyi kendi içeriğine göre yorumlayıp bir boyut seçer; ebeveyn de çocuğu seçilen boyutla kendi alanında bir yere koyar. Çocuk öneriyi kabul edebilir, küçük kalabilir ya da öneriden büyük bir boyut isteyebilir. Aşağıdaki parça adımları kaynak olarak gösterir.

```swift
// Kaynak parca: oneri, secim ve yerlestirme
import SwiftUI

struct SummaryPanel: View {
    @State private var isCompact = false

    var body: some View {
        VStack {
            Text("Ozet")
                .layoutPriority(isCompact ? 0 : 1)
            Rectangle()
                .frame(maxWidth: .infinity, minHeight: isCompact ? 40 : 120)
            Text("Not")
                .lineLimit(2)
        }
    }
}
```

`isCompact` panelin kendi durumudur ve iki yerde yer önerisini etkiler: başlığın düzen önceliği ile grafiğin asgari yüksekliği. Notun satır sınırı sabittir. `layoutPriority` ise yer daraldığında hangi çocuğun önce yer alacağını söyler; yüksek öncelikli çocuk önce boyutunu seçer, kalan yer öteki çocuklara bölüşülür. Bu parça KAYNAK'tır ve boyutların sayı olarak ne çıktığı bu derste ölçülmedi.

**GV11.** Bu ölçüm düzenin üç adımını anlatır ama boyut hesabı yapmaz. Önerilen boyutun hangi sayıya dönüştüğü, `layoutPriority` değerlerinin bölüşümü ve seçilen boyutların yerleştirmesi ölçülmedi.

## Önerinin Dayandığı Değer

Öneriyi belirleyen değer ebeveynin durumundaysa, çocuğun bunu okuması ebeveyn tetiği üretir. Aşağıdaki ağaçta `isCompact` ve `density` panelin değerleridir; başlık ve grafik bunları okur. Yazı boyutu tercihi (`dynamicTypeSize`) ise ortamdan gelir ve başlık ile notun yer ihtiyacını etkiler.

```swift
// main.swift — onerilen boyutu belirleyen deger ebeveyn, yazi boyutu ortam
let storage: [String: Storage] = [
    "isCompact": .state(owner: "SummaryPanel"),
    "density": .state(owner: "SummaryPanel"),
    "dynamicTypeSize": .environment,
]

let screen = ViewTree(nodes: [
    ViewNode("SummaryPanel", parent: nil, reads: ["isCompact", "density"]),
    ViewNode("SummaryTitle", parent: "SummaryPanel", reads: ["isCompact", "dynamicTypeSize"]),
    ViewNode("SummaryChart", parent: "SummaryPanel", reads: ["isCompact", "density"]),
    ViewNode("SummaryNote", parent: "SummaryPanel", reads: ["dynamicTypeSize"]),
], storage: storage)

let recomputes = [
    screen.change("kompakt-oldu", key: "isCompact"),
    screen.change("yogunluk-degisti", key: "density"),
    screen.change("yazi-boyutu-degisti", key: "dynamicTypeSize"),
].flatMap { $0 }

countCauses(recomputes)
```

```
kompakt-oldu: isCompact degisti | yeniden SummaryPanel yerel, SummaryTitle ebeveyn, SummaryChart ebeveyn | atlanan SummaryNote
yogunluk-degisti: density degisti | yeniden SummaryPanel yerel, SummaryChart ebeveyn | atlanan SummaryTitle,SummaryNote
yazi-boyutu-degisti: dynamicTypeSize degisti | yeniden SummaryTitle ortam, SummaryNote ortam | atlanan SummaryPanel,SummaryChart
yerel: 2
ebeveyn: 3
gozlem: 0
ortam: 2
```

`kompakt-oldu` satırında panel yerel, başlık ve grafik ebeveyn tetiğiyle yeniden hesaplandı; not atlandı. `yogunluk-degisti` satırında yalnız grafik okuduğu için panel yerel, grafik ebeveyn. `yazi-boyutu-degisti` satırında panel ve grafik atlandı, başlık ile not ortam tetiğiyle yeniden hesaplandı. Yazı boyutu tercihini kullanıcı sistem ayarından değiştirir; hiçbir ebeveynin durumu bu değerin sahibi değildir.

Notun `isCompact` değerini okumaması kaynak parçayla uyumludur: satır sınırı sabit bir sayıdır. Okuma kümesi kaynak parçanın okumasından türetilir; kaynakta bulunmayan okuma varsayımdır ve GV12'de belirtilir; not yalnız yazı boyutuna bağlı kaldığı için `kompakt-oldu` satırında atlanır.

**GV12.** Bu ölçüm `isCompact`, `density` ve `dynamicTypeSize` için. Kaynak parçada görünmeyen `density` değerinin panelin durumu olduğu ve yalnız grafiğin onu okuduğu varsayıldı; bu bir ölçüm kuralı değil, ağaç tanımıdır.

## Sınırlayıcı Ölçüm

Önerilen boyut bir durum değeri değildir. Ebeveyn ile çocuk arasındaki bir görüşmedir: ebeveyn önerir, çocuk seçer ve sonuç yerleşimde ortaya çıkar. Modelde bu görüşmenin bir anahtarı yoktur. Grafik `proposedWidth` değerini okuyor gibi yazılsa bile, model bunu saklama tablosunda bulamaz ve tetiği ölçüm dışı sayar.

```swift
// main.swift — onerilen genislik tabloda yoksa tetik olcum disidir
let storage: [String: Storage] = [
    "isCompact": .state(owner: "SummaryPanel"),
]

let screen = ViewTree(nodes: [
    ViewNode("SummaryPanel", parent: nil, reads: ["isCompact"]),
    ViewNode("SummaryChart", parent: "SummaryPanel", reads: ["isCompact", "proposedWidth"]),
    ViewNode("SummaryNote", parent: "SummaryPanel", reads: []),
], storage: storage)

let recomputes = [
    screen.change("genislik-onerildi", key: "proposedWidth"),
    screen.change("kompakt-oldu", key: "isCompact"),
].flatMap { $0 }

countCauses(recomputes)
```

```
genislik-onerildi: proposedWidth degisti | yeniden SummaryChart olcum-disi | atlanan SummaryPanel,SummaryNote
kompakt-oldu: isCompact degisti | yeniden SummaryPanel yerel, SummaryChart ebeveyn | atlanan SummaryNote
yerel: 1
ebeveyn: 1
gozlem: 0
ortam: 0
```

`genislik-onerildi` satırı çekirdeğin ölçemediği satırdır: grafik değeri okuduğu için listelenir, ama satır `olcum-disi` yazar ve bir yeniden hesaplama iddiası değildir; sayaç da onu göstermez. Model burada bir hesap yapmaz: önerilen genişliğin sayı olarak ne olduğunu, grafiğin ne seçtiğini ya da paneldeki yerleşimi bilmez. Yalnız hangi görünümün hangi anahtarı okuduğunu ve anahtarın tabloda olup olmadığını söyler. `kompakt-oldu` satırı ise tabloda olan değer için sonucun nasıl değiştiğini gösterir.

**GV13.** Bu ölçüm boyut görüşmesini tek bir anahtara indirger ve o anahtarın tabloda olmadığı durumu inceler. Gerçek bir boyut değişiminin hangi görünümleri yeniden hesaplattığı, çerçevenin yerleşim geçişleri ve çocuğun öneriye verdiği yanıt ölçülmedi.

## Özet

- Düzen üç adımdır: ebeveyn önerir, çocuk boyutunu seçer, ebeveyn çocuğu yerleştirir.
- Önerilen boyutu belirleyen değer ebeveynin durumundaysa, onu okuyan çocuk ebeveyn tetiğiyle yeniden hesaplanır.
- Yazı boyutu tercihi ortamdan gelir ve ortam tetiği üretir.
- `layoutPriority` yer daraldığında kimin önce boyut seçeceğini belirler; sayısal bölüşümü bu derste ölçülmedi.
- Önerilen boyut bir durum değeri değildir; modelde anahtarı yoksa tetik ölçüm dışı sınıflanır.
- Bu dersin tetiği: **ebeveyn**.

## Sonraki Adım

Bu derste ebeveyn değeri, çocuğa önerilen boyutun dayanağıydı. Sıradaki derste aynı soruyu ızgara için soruyoruz: bir ızgaranın kaç sütun gösterdiğini ne belirler. Cevabın bir kısmı ortamdan gelen bir boyut sınıfıdır; bu yüzden tetik de ortam olacaktır.
