@State — шта је то, намена и употреба у SwiftUI

Аутор: IT Sectr Објављено: 2026-06-19 Време читања: 7 мин

@State је Property Wrapper у SwiftUI-ју за управљање локалним стањем унутар једног приказа. SwiftUI аутоматски прецртава приказ при свакој промени @State својства, чинећи интерфејс реактивним без ручних позива за ажурирање. Према Apple Developer Documentation (2025), @State се препоручује за једноставне типове и структуре које припадају једном приказу. @State је најједноставнији начин да додате интерактивност SwiftUI интерфејсу.

Главно

  • @State — Property Wrapper за локално стање које припада једном приказу
  • Аутоматско ажурирање — SwiftUI поново покреће body при промени @State својства
  • Једноставни типови — @State одговара за String, Int, Bool, enum и структуре
  • Не прослеђивати угњежденим приказима — за измену из дечјих компоненти користите @Binding
  • private — @State својства се увек декларишу са модификатором private

Шта је @State у SwiftUI-ју?

@State је Property Wrapper уграђен у SwiftUI који омогућава приказу да складишти и прати сопствено стање. Када се вредност @State промени, SwiftUI аутоматски прецртава приказ, поново позивајући својство body. Ово је основа реактивног програмирања у SwiftUI-ју: програмер декларише стање, а оквир преузима синхронизацију интерфејса.

@State ствара област за складиштење на хрпи којом управља SwiftUI. Ова област је перзистентна — преживљава поновне иницијализације структуре приказа које се дешавају при сваком рендеровању. SwiftUI користи идентификатор приказа (генерисан на основу позиције у хијерархији) за повезивање @State својства са одређеним приказом. Захваљујући томе, стање се не ресетује при ажурирању родитељског приказа.

Важно ограничење: @State је намењен само за вредносне типове (структуре, набрајања, примитиве). За референцне типове (класе) користите @StateObject или @ObservedObject. Ако доделите класу @State својству, SwiftUI неће моћи да открије промене унутар објекта — само замену референце у целини.

Како @State ради испод хаубе?

SwiftUI имплементира @State кроз унутрашњи механизам Storage. Свако @State својство добија наменску меморијску ћелију која се чува у посебном storage контејнеру приказа. Када дође до уписа у wrappedValue, SwiftUI преко didSet обавештава свој граф зависности (dependency graph) о потреби за прецртавањем.

swift
struct ContentView: View {
    @State private var name: String = "User"
    @State private var isLoggedIn: Bool = false

    var body: some View {
        VStack {
            Text("Здраво, \(name)")
            Button(isLoggedIn ? "Одјава" : "Пријава") {
                isLoggedIn.toggle()
            }
        }
    }
}

У примеру су два @State својства: name (String) и isLoggedIn (Bool). При позиву isLoggedIn.toggle(), SwiftUI означава ContentView као захтеван за ажурирање и поново покреће body у следећем циклусу рендеровања. Кључна тачка: @State својства се увек декларишу са модификатором private — то је сигнал да стање припада искључиво тренутном приказу и не треба да се мења споља директно.

За посматрање промена, SwiftUI користи CurrentValueSubject из Combine-а. Свако @State својство ствара скривеног издавача који обавештава систем при свакој промени. Ово омогућава SwiftUI-ју да прецртава само минимално неопходан скуп приказа, избегавајући потпуно ажурирање хијерархије.

Када користити @State у пројекту

@State је оптималан за једноставна локална стања: текстуална поља за претрагу, булове заставице за модалне прозоре, прекидачи подешавања, бројачи, изабрани елементи листе. Ако се вредност користи само у једном приказу и његовим угњежденим компонентама (путем @Binding), @State је прави избор. За стања која треба да преживе затварање приказа (нпр. подаци форме), @State је такође погодан, док приказ остаје у хијерархији.

  • Текстуална поља — @State за складиштење унетог текста у TextField
  • Булове заставице — @State за приказивање/сакривање модалних прозора и sheet
  • Избор елемената — @State за праћење изабране картице или реда
  • Бројачи — @State за нумеричке вредности са инкрементом/декрементом
  • Посредна израчунавања — @State за кеширање резултата унутар приказа

Не користите @State за глобална стања апликације, кеширање мрежних података или објеката који се користе на више екрана. За ове намене су намењени @StateObject и @EnvironmentObject. Такође, @State није погодан за складиштење великих количина података — сваки пут када се промени, цео приказ ће бити прецртан.

@State и @Binding: заједнички рад

@Binding је мост између @State у родитељском приказу и дечјем приказу који треба да мења ово стање. Родитељ декларише @State, а дечја компонента добија Binding кроз пројекцију $. Промена Binding-а у дечјем приказу аутоматски ажурира @State код родитеља — и обрнуто. Ово обезбеђује једносмерни ток података са могућношћу повратне спреге.

swift
struct ParentView: View {
    @State private var text: String = ""

    var body: some View {
        ChildView(text: $text)
    }
}

struct ChildView: View {
    @Binding var text: String

    var body: some View {
        TextField("Enter text", text: $text)
    }
}

У листингу, ParentView поседује @State text, а ChildView прима $text као Binding. TextField унутар ChildView-а се везује за овај Binding преко text: $text. Када корисник куца у TextField-у, вредност се мења у ChildView-у кроз Binding, што изазива ажурирање @State у ParentView-у. Оба приказа се прецртавају са новом вредношћу.

Типичне грешке при раду са @State

Најчешћа грешка — додељивање класе @State својству. Ако напишете @State var model = MyClass(), SwiftUI неће моћи да прати промене својстава унутар класе — само замену самог објекта. За класе увек користите @StateObject. Други уобичајени проблем — декларисање @State без модификатора private, што нарушава принцип инкапсулације стања.

Директно прослеђивање @State дечјем приказу без $ — још једна типична грешка. Ако проследите TextField(text: text) уместо TextField(text: $text), дечја компонента ће добити обичан стринг, а не Binding. Промена текста у TextField-у неће бити синхронизована са родитељским @State. Увек користите пројекцију $ за прослеђивање Binding-а.

Трећа грешка — вишеструка @State својства за повезане податке. Ако неколико вредности логички чине једну целину (нпр. поља форме), спојите их у једну структуру са једним @State. Ово поједностављује прослеђивање стања дечјим приказима и смањује број одвојених окидача за ажурирање.

Примери употребе @State у SwiftUI-ју

@State се користи у већини SwiftUI пројеката за основну интерактивност. Размотримо пример форме за пријаву, где @State управља текстуалним пољима и стањем учитавања. Овај образац се среће у свакој апликацији — од једноставних белешки до сложених корпоративних решења.

swift
struct LoginView: View {
    @State private var email: String = ""
    @State private var password: String = ""
    @State private var isLoading: Bool = false
    @State private var errorMessage: String?

    var body: some View {
        Form {
            TextField("Email", text: $email)
            SecureField("Password", text: $password)
            Button("Пријава") {
                login()
            }.disabled(isLoading)
        }
    }

    private func login() {
        isLoading = true
        // Изврши мрежни захтев
    }
}

У примеру су четири @State својства: email и password за поља форме, isLoading за индикацију учитавања и errorMessage за приказивање грешака. Свако својство независно управља својим делом интерфејса. При промени isLoading, дугме се аутоматски блокира кроз disabled(isLoading) — без ручног ажурирања UI-ја.

Често постављана питања

Зашто се @State декларише са private?

@State је намењен за локално стање одређеног приказа. Модификатор private гарантује да друге компоненте не могу директно да га мењају, нарушавајући инкапсулацију. За спољни приступ користите пројекцију $.

Може ли @State да садржи низ или речник?

Да, @State подржава низове и речнике, јер су то вредносни типови. Међутим, при промени елемента низа SwiftUI прецртава цео приказ. За велике листе ефикасније је користити @StateObject са @Published.

Шта се дешава при додељивању nil @State својству са Optional типом?

@State исправно ради са Optional типовима. При додељиванию nil, SwiftUI открива промену и прецртава приказ. Ово је згодно за стања попут errorMessage: String?, где nil значи одсуство грешке.

Како се @State понаша при поновном појављивању приказа?

@State чува вредност док приказ остаје у хијерархији. Ако се приказ уклони из хијерархије и поново дода, @State се иницијализује изнова са подразумеваном вредношћу. За перзистентност користите @AppStorage.

Могу ли се анимирати промене @State?

Да, умотајте промену у withAnimation: withAnimation(.easeInOut) { isExpanded.toggle() }. SwiftUI анимира прелаз између старог и новог стања интерфејса са наведеним типом анимације.

Закључак

  • @State — Property Wrapper за локално стање једног приказа, аутоматски ажурира интерфејс
  • Одговара за једноставне типове: String, Int, Bool, као и структуре и enum
  • Не одговара за референцне типове (класе) — користите @StateObject
  • Увек private — стање не треба да се мења споља директно
  • Пројекција $ — ствара Binding за пренос права измене дечјим приказима
  • Више @State у једном приказу — нормална пракса за независна стања
  • withAnimation — омогућава анимирање промена @State својстава

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође