@Binding — co to je, jak funguje a příklady ve SwiftUI

Autor: IT Sectr Publikováno: 2026-06-19 Doba čtení: 7 min

@Binding je Property Wrapper ve SwiftUI, který vytváří odkaz na data vlastněná jinou komponentou. Binding neukládá hodnotu samostatně — pouze poskytuje přístup k existujícímu zdroji pravdy prostřednictvím projekce $. Podle Apple Developer Documentation (2025) poskytuje Binding reaktivní obousměrné propojení mezi rodičovským a podřízeným zobrazením bez přímého vlastnictví dat. @Binding je klíčový mechanismus pro předávání měnitelného stavu dolů hierarchií.

Hlavní body

  • @Binding — Property Wrapper pro vytvoření odkazu na stav rodičovského zobrazení
  • Bez vlastnictví — Binding neukládá data, pouze poskytuje přístup ke zdroji pravdy
  • Projekce $ — $stateValue vytváří Binding z @State nebo @StateObject
  • Obousměrné propojení — změny v podřízeném zobrazení se okamžitě projeví v rodiči
  • Binding.constant — pevná hodnota pro prototypování bez zpětné vazby

Co je @Binding ve SwiftUI?

@Binding je Property Wrapper, který vytváří obousměrné propojení mezi vlastností uloženou v rodičovském zobrazení a podřízenou komponentou. Hlavní rozdíl mezi Binding a @State: Binding nevlastní data. Pouze čte a zapisuje hodnotu prostřednictvím skutečného zdroje — @State, @StateObject nebo jiného Binding v rodiči. Bez Binding by podřízená zobrazení nemohla měnit stav předka bez callbacků nebo delegátů.

Binding je implementován jako struktura se dvěma vlastnostmi: wrappedValue (aktuální hodnota) a projectedValue (samotný Binding, přístupný přes $). Když podřízené zobrazení změní wrappedValue prostřednictvím Binding, SwiftUI přenese změnu do zdroje dat a překreslí všechna závislá zobrazení. To se děje synchronně v rámci aktuálního cyklu aktualizace.

Důležitá vlastnost: @Binding není omezen na jednodrovňové předávání. Binding lze předávat přes více úrovní hierarchie — každá podřízená komponenta obdrží odkaz na stejný zdroj dat. Změna na jakékoli úrovni způsobí jednotnou aktualizaci všech propojených zobrazení.

Jak funguje obousměrné propojení Binding

Mechanismus obousměrného propojení prostřednictvím @Binding je založen na projekci Property Wrapperů. Když rodič deklaruje @State var value: T, SwiftUI automaticky vygeneruje projekci $value typu Binding. Předáním $value do podřízené komponenty s @Binding var value: T propojíte obě zobrazení s jednou paměťovou buňkou. Jakýkoli zápis prostřednictvím Binding v podřízeném zobrazení způsobí překreslení obou komponent.

swift
struct SliderContainer: View {
    @State private var value: Double = 0.5

    var body: some View {
        VStack {
            Text("Hodnota: \(value)")
            SliderView(value: $value)
        }
    }
}

struct SliderView: View {
    @Binding var value: Double

    var body: some View {
        Slider(value: $value, in: 0...1)
    }
}

V příkladu SliderContainer vlastní @State value a SliderView obdrží Binding prostřednictvím $value. Posuvník uvnitř SliderView je připojen k tomuto Binding. Při přetažení posuvníku Slider změní hodnotu prostřednictvím Binding, což automaticky aktualizuje @State v SliderContainer a obě zobrazení zobrazí aktuální číslo. Celý řetězec funguje bez jediného callbacku nebo oznámení.

Pro vytvoření Binding z @StateObject nebo @ObservedObject se používá stejná projekce: $object.property dává Binding. To umožňuje předávat jednotlivé vlastnosti ObservableObject do podřízených zobrazení bez předávání celého objektu. Tento přístup poskytuje užší propojení a zabraňuje zbytečným překreslením.

@Binding vs callbacky: co vybrat

Před SwiftUI byl standardní způsob předávání změn nahoru hierarchií prostřednictvím callbacků a delegátů: rodič předával closure, podřízená komponenta jej volala při změně. @Binding nabízí alternativu s méně kódem a deklarativnější syntaxí. Místo předávání dokončovacího closure stačí předat $stateValue.

Kritérium@BindingCallbacky
KódJedna anotace + $Closure + volání
VíceúrovňovostAutomatickáŘetězec closure
TestováníBinding(value:constant)Mock-closure
ČitelnostVysokáStřední
FlexibilitaPouze dataLibovolná logika

Použijte @Binding, když podřízené zobrazení potřebuje pouze číst a měnit hodnotu. Pokud jsou při změně vyžadovány vedlejší akce (validace, logování, síťový požadavek), kombinujte Binding s callbackem: předávejte Binding pro data a closure pro události. Například TextField se může připojit k Binding a onChange spustí validaci.

Vzory použití @Binding v projektech

@Binding se uplatňuje v několika typických scénářích. První — vlastní ovládací prvky: přepínače, posuvníky, výběry barev a další interaktivní prvky přijímají Binding pro obousměrnou synchronizaci. Druhý — modální okna: příznak zobrazení sheet je předáván jako Binding, což umožňuje podřízenému zobrazení zavřít se prostřednictvím presentationMode nebo přímým nastavením.

Třetí vzor — formuláře s rozdělením. Pokud formulář sestává z mnoha polí, každé pole lze extrahovat do samostatné komponenty přijímající Binding pro svou hodnotu. To zjednodušuje testování a opětovné použití polí mezi různými formuláři. Rodičovská komponenta zůstává jediným vlastníkem celého modelu formuláře.

swift
struct FormField: View {
    let title: String
    @Binding var text: String

    var body: some View {
        VStack(alignment: .leading) {
            Text(title).font(.caption)
            TextField("Enter \(title.lowercased())", text: $text)
                .textFieldStyle(.roundedBorder)
        }
    }
}

Komponenta FormField přijímá popisek a Binding na řetězec. Zobrazuje štítek a TextField připojený k předanému Binding. Jakýkoli formulář může používat FormField opakovaně předáváním $property pro každé pole. To snižuje duplicitu značek a centralizuje stylování textových polí.

Vytváření vlastních Binding

SwiftUI umožňuje ruční vytváření Binding prostřednictvím inicializátoru Binding(get:set:). To je užitečné, když je třeba přidat logiku při čtení nebo zápisu hodnoty. Můžete například vytvořit Binding, který formátuje číslo před uložením, nebo Binding, který synchronizuje hodnotu se vzdáleným serverem při každé změně.

swift
struct ValidatedField: View {
    @State private var email: String = ""

    var emailBinding: Binding<String> {
        .init(
            get: { email },
            set: { email = $0.lowercased().trimmingCharacters(in: .whitespaces) }
        )
    }

    var body: some View {
        TextField("Email", text: emailBinding)
    }
}

Ve výpisu vlastní emailBinding automaticky převádí text na malá písmena a odstraňuje mezery při každé změně. TextField používá tento Binding místo přímého připojení k $email. Tento přístup umožňuje centralizovat validaci a transformaci dat uvnitř Binding, aniž by se kód zanášel onChange handlerem.

Chyby a antivzory s @Binding

První a nejčastější chyba — předávání hodnoty místo Binding. Pokud podřízená komponenta deklaruje @Binding var text: String a rodič předá text (bez $), kompilátor vyhlásí chybu: Cannot convert value of type 'String' to expected argument type 'Binding'. Řešení — vždy používejte prefix $ při předávání: $text.

Druhá chyba — Binding na data pouze pro čtení. Pokud podřízené zobrazení potřebuje pouze číst hodnotu, nepoužívejte @Binding — stačí obyčejné let nebo @State z rodiče. Binding implikuje možnost zápisu a další práva na změnu komplikují ladění a porušují princip minimálních oprávnění.

Třetí problém — Binding.constant v produkci. Binding.constant(value) vytváří falešné propojení bez zpětné vazby — změny jsou ignorovány. Používejte constant pouze pro prototypování a náhledy (Xcode Previews), ale nikdy v reálném kódu. Pro testy používejte Binding(get:set:) s řízeným chováním.

Často kladené otázky

Jaký je rozdíl mezi @Binding a @State?

@State vlastní data a spravuje jejich ukládání na haldě. @Binding pouze odkazuje na existující stav bez vlastnictví. @State je vždy private, @Binding — vstupní parametr podřízeného zobrazení.

Lze vytvořit Binding bez @State?

Ano, prostřednictvím inicializátoru Binding(get:set:) nebo Binding.constant(value). Binding lze také získat z @StateObject pomocí projekce $object.$property a z Publisher pomocí Binding(get:set:) uvnitř Subscribe.

Jak předat Binding přes několik úrovní vnoření?

@Binding se předává v řetězci: každá mezilehlá komponenta deklaruje @Binding a předává jej dále pomocí $. Všechny úrovně odkazují na jeden zdroj dat v kořenovém zobrazení.

Proč Binding.constant neaktualizuje rozhraní?

Binding.constant vytváří tichý obal — setter ignoruje nové hodnoty. Je určen pouze pro prototypování a SwiftUI Previews, kde není vyžadována zpětná vazba od podřízené komponenty.

Může být @Binding volitelný?

Ano, Binding<T?> je podporován. Pokud předáte Binding<String?>, podřízené zobrazení může nastavit nil. To je užitečné pro volitelná pole formulářů nebo stavy s možností resetování.

Shrnutí

  • @Binding — Property Wrapper pro obousměrné propojení s daty rodičovského zobrazení
  • Nevlastní data — pouze poskytuje přístup ke zdroji pravdy
  • Projekce $ převádí @State, @StateObject na Binding pro předání podřízeným zobrazením
  • Vlastní Binding se vytváří pomocí Binding(get:set:) s další logikou
  • Binding.constant — pouze pro náhledy a prototypy
  • Víceúrovňové předávání — Binding prochází libovolnou hloubkou vnoření
  • Alternativa k callbackům — deklarativní způsob změny stavu z podřízených komponent

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také