@State — SwiftUI-də bir görünüş daxilində lokal vəziyyəti idarə etmək üçün Property Wrapper-dir. SwiftUI @State xassəsi hər dəfə dəyişdikdə görünüşü avtomatik olaraq yenidən çəkir və interfeysi əl ilə yeniləmə zəngləri olmadan reaktiv edir. Apple Developer Documentation (2025)-yə görə, @State bir görünüşə aid sadə tiplər və strukturlar üçün tövsiyə olunur. @State — SwiftUI interfeysinə interaktivlik əlavə etməyin ən sadə yoludur.
Əsas məqamlar
@State — SwiftUI-yə daxil edilmiş Property Wrapper-dir ki, görünüşə öz vəziyyətini saxlamağa və izləməyə imkan verir. @State dəyəri dəyişdikdə, SwiftUI avtomatik olaraq görünüşü yenidən çəkir və body xassəsini yenidən çağırır. Bu, SwiftUI-də reaktiv proqramlaşdırmanın əsasıdır: tərtibatçı vəziyyəti elan edir, framework isə interfeysin sinxronizasiyasını öz üzərinə götürür.
@State SwiftUI tərəfindən idarə olunan yığında saxlama sahəsi yaradır. Bu sahə davamlıdır — hər render zamanı baş verən görünüş strukturunun təkrar initləşdirilmələrindən qorunur. SwiftUI @State xassəsini konkret görünüşə bağlamaq üçün görünüş identifikatorundan (ierarxiyada mövqeyə əsasən yaradılmış) istifadə edir. Bunun sayəsində valideyn görünüşü yeniləndikdə vəziyyət sıfırlanmır.
Əhəmiyyətli məhdudiyyət: @State yalnız dəyər tipləri (strukturlar, enumlar, primitivlər) üçün nəzərdə tutulub. İstinad tipləri (siniflər) üçün @StateObject və ya @ObservedObject istifadə edin. Bir sinfi @State xassəsinə təyin etsəniz, SwiftUI obyekt daxilindəki dəyişiklikləri aşkar edə bilməyəcək — yalnız referansın tam dəyişdirilməsini.
SwiftUI @State-i daxili Storage mexanizmi vasitəsilə həyata keçirir. Hər bir @State xassəsi görünüşün xüsusi storage konteynerində saxlanılan ayrılmış yaddaş hücrəsi alır. wrappedValue-a yazıldıqda, SwiftUI didSet vasitəsilə asılılıq qrafikini (dependency graph) yenidən çəkmə zərurəti barədə xəbərdar edir.
struct ContentView: View {
@State private var name: String = "User"
@State private var isLoggedIn: Bool = false
var body: some View {
VStack {
Text("Salam, \(name)")
Button(isLoggedIn ? "Çıxış" : "Giriş") {
isLoggedIn.toggle()
}
}
}
}
Nümunədə iki @State xassəsi var: name (String) və isLoggedIn (Bool). isLoggedIn.toggle() çağırıldıqda SwiftUI ContentView-i yenilənmə tələb edən kimi qeyd edir və növbəti render dövründə body-ni yenidən işə salır. Əsas məqam: @State xassələri həmişə private modifikatoru ilə elan edilir — bu, vəziyyətin yalnız cari görünüşə aid olduğunu və kənardan birbaşa dəyişdirilməməsi lazım olduğunu göstərir.
Dəyişiklikləri izləmək üçün SwiftUI Combine-dən CurrentValueSubject istifadə edir. Hər bir @State xassəsi hər dəyişiklikdə sistemi xəbərdar edən gizli bir nəşrçi yaradır. Bu, SwiftUI-yə ierarxiyanın tam yenilənməsindən qaçaraq yalnız minimum zəruri görünüş dəstini yenidən çəkməyə imkan verir.
@State sadə lokal vəziyyətlər üçün optimaldır: axtarış mətn sahələri, modal pəncərələr üçün boolean bayraqlar, tənzimləmə açarları, sayğaclar, seçilmiş siyahı elementləri. Əgər dəyər yalnız bir görünüşdə və onun iç-içə komponentlərində (@Binding vasitəsilə) istifadə olunursa, @State düzgün seçimdir. Görünüşün bağlanmasından sonra da qalmalı olan vəziyyətlər üçün (məsələn, formal məlumatları) @State uyğundur, görünüş ierarxiyada qaldığı müddətcə.
@State-dən qlobal tətbiq vəziyyətləri, şəbəkə məlumatlarının keşlənməsi və ya bir neçə ekranda istifadə olunan obyektlər üçün istifadə etməyin. Bu məqsədlər üçün @StateObject və @EnvironmentObject nəzərdə tutulub. @State həmçinin böyük həcmli məlumatların saxlanması üçün uyğun deyil — hər dəfə dəyişiklikdə bütün görünüş yenidən çəkiləcək.
@Binding — valideyn görünüşündəki @State ilə bu vəziyyəti dəyişməli olan uşaq görünüşü arasında körpüdür. Valideyn @State elan edir, uşaq komponent isə $ proyeksiyası vasitəsilə Binding alır. Uşaq görünüşdə Binding-in dəyişdirilməsi avtomatik olaraq valideyndəki @State-i yeniləyir — və əksinə. Bu, əks əlaqə imkanı ilə bir istiqamətli məlumat axınını təmin edir.
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)
}
}
Listinqdə ParentView @State text-in sahibidir, ChildView isə $text-i Binding kimi alır. ChildView daxilindəki TextField text: $text vasitəsilə bu Binding-ə bağlanır. İstifadəçi TextField-də yazdıqda, dəyər ChildView-də Binding vasitəsilə dəyişir, bu da ParentView-də @State-in yenilənməsinə səbəb olur. Hər iki görünüş yeni dəyərlə yenidən çəkilir.
Ən çox yayılmış səhv @State xassəsinə sinif təyin etməkdir. @State var model = MyClass() yazsanız, SwiftUI sinif daxilindəki xassələrin dəyişikliklərini izləyə bilməyəcək — yalnız obyektin özünün dəyişdirilməsini. Siniflər üçün həmişə @StateObject istifadə edin. İkinci ümumi problem — @State-in private modifikatoru olmadan elan edilməsi, bu, vəziyyətin inkapsulyasiya prinsipini pozur.
@State-in birbaşa ötürülməsi uşaq görünüşə $ olmadan — başqa bir tipik səhv. Əgər TextField(text: $text) əvəzinə TextField(text: text) ötürsəniz, uşaq komponent Binding yox, sadəcə string alacaq. TextField-də mətnin dəyişdirilməsi valideyn @State ilə sinxronlaşdırılmayacaq. Binding ötürmək üçün həmişə $ proyeksiyasından istifadə edin.
Üçüncü səhv — əlaqəli məlumatlar üçün çoxsaylı @State xassələri. Əgər bir neçə dəyər məntiqi olaraq vahid bir bütöv təşkil edirsə (məsələn, forma sahələri), onları tək @State ilə bir strukturda birləşdirin. Bu, vəziyyətin uşaq görünüşlərə ötürülməsini sadələşdirir və ayrı-ayrı yeniləmə tetikleyicilərinin sayını azaldır.
@State əksər SwiftUI layihələrində əsas interaktivlik üçün istifadə olunur. @State-in mətn sahələrini və yükləmə vəziyyətini idarə etdiyi giriş forması nümunəsinə baxaq. Bu nümunə hər bir tətbiqdə — sadə qeydlərdən tutmuş mürəkkəb korporativ həllərə qədər rast gəlinir.
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("Giriş") {
login()
}.disabled(isLoading)
}
}
private func login() {
isLoading = true
// Şəbəkə sorğusu yerinə yetir
}
}
Nümunədə dörd @State xassəsi var: email və password forma sahələri üçün, isLoading yükləmə göstəricisi üçün və errorMessage xəta mesajlarını göstərmək üçün. Hər bir xassə interfeysin öz hissəsini müstəqil idarə edir. isLoading dəyişdikdə düymə disabled(isLoading) vasitəsilə avtomatik bloklanır — UI-nin əl ilə yenilənməsi olmadan.
Tez-tez verilən suallar
@State konkret görünüşün lokal vəziyyəti üçün nəzərdə tutulub. private modifikatoru digər komponentlərin onu birbaşa dəyişməsinin qarşısını alır, inkapsulyasiyanı qoruyur. Xarici giriş üçün $ proyeksiyasından istifadə edin.
Bəli, @State massivləri və lüğətləri dəstəkləyir, çünki bunlar dəyər tipləridir. Lakin massivin elementini dəyişdikdə SwiftUI bütün görünüşü yenidən çəkir. Böyük siyahılar üçün @Published ilə @StateObject istifadə etmək daha səmərəlidir.
@State Optional tipləri ilə düzgün işləyir. Nil təyin edildikdə SwiftUI dəyişikliyi aşkarlayır və görünüşü yenidən çəkir. Bu, errorMessage: String? kimi vəziyyətlər üçün əlverişlidir, burada nil xətanın olmaması deməkdir.
@State görünüş ierarxiyada qaldığı müddətcə dəyəri qoruyur. Əgər görünüş ierarxiyadan silinib yenidən əlavə olunarsa, @State standart dəyərlə yenidən initləşir. Davamlılıq üçün @AppStorage istifadə edin.
Bəli, dəyişikliyi withAnimation ilə əhatə edin: withAnimation(.easeInOut) { isExpanded.toggle() }. SwiftUI müəyyən edilmiş animasiya növü ilə interfeysin köhnə və yeni vəziyyəti arasında keçidi animasiya edir.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun