@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 λαμβάνει ένα αποκλειστικό κελί μνήμης που αποθηκεύεται στο ειδικό κοντέινερ αποθήκευσης του οράματος. Όταν συμβαίνει εγγραφή στο 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 είναι βέλτιστο για απλές τοπικές καταστάσεις: πεδία κειμένου αναζήτησης, boolean σημαίες για modal παράθυρα, διακόπτες ρυθμίσεων, μετρητές, επιλεγμένα στοιχεία λίστας. Εάν η τιμή χρησιμοποιείται μόνο σε ένα όραμα και στα ένθετα στοιχεία του (μέσω @Binding), το @State είναι η σωστή επιλογή. Για καταστάσεις που πρέπει να επιβιώσουν από το κλείσιμο του οράματος (π.χ. δεδομένα φόρμας), το @State είναι επίσης κατάλληλο όσο το όραμα παραμένει στην ιεραρχία.

  • Πεδία κειμένου — @State για αποθήκευση εισαγόμενου κειμένου σε TextField
  • Boolean σημαίες — @State για εμφάνιση/απόκρυψη modal παραθύρων και 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), το θυγατρικό στοιχείο θα λάβει ένα απλό string, όχι 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. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης