Το SwiftUI είναι ένα declarative framework της Apple για τη δημιουργία διεπαφών χρήστη σε όλες τις πλατφόρμες του οικοσυστήματος. Αντί για την προστακτική περιγραφή βημάτων, ο προγραμματιστής δηλώνει πώς πρέπει να μοιάζει η διεπαφή και το SwiftUI διαχειρίζεται την απόδοση και την ενημέρωσή της. Σύμφωνα με το Apple Developer Documentation (2025), το SwiftUI υποστηρίζει iOS 15+, iPadOS 15+, macOS 12+, watchOS 8+ και tvOS 15+ και χρησιμοποιεί το View Protocol ως βασικό δομικό στοιχείο για όλα τα στοιχεία της διεπαφής.
Βασικά σημεία
body — η βάση κάθε στοιχείου UI στο SwiftUI, που επιστρέφει την περιγραφή της οθόνης μέσω σύνθεσης views.Το SwiftUI είναι ένα declarative framework, που παρουσιάστηκε από την Apple το 2019 για να αντικαταστήσει το UIKit σε νέα έργα. Αντί να δημιουργεί χειροκίνητα στιγμιότυπα UIView και να τα προσθέτει στην ιεραρχία, ο προγραμματιστής περιγράφει τη διεπαφή μέσω δομών που υλοποιούν το πρωτόκολλο View. Το SwiftUI υπολογίζει αυτόματα τη διαφορά μεταξύ της τρέχουσας και της νέας κατάστασης και ανασχεδιάζει μόνο τα τροποποιημένα μέρη χρησιμοποιώντας τη δική του μηχανή απόδοσης.
Το framework είναι γραμμένο σε Swift χρησιμοποιώντας value semantics (δομές, όχι κλάσεις), κάτι που καθιστά τα στοιχεία UI ελαφριά και thread-safe. Σε αντίθεση με το UIKit, όπου ένα UIViewController μπορεί να ζυγίζει 200+ bytes λόγω του Objective-C runtime, ένα SwiftUI View είναι απλώς μια δομή μεγέθους λίγων bytes. Αυτό είναι ιδιαίτερα σημαντικό για το watchOS με την περιορισμένη μνήμη του.
Η ίδια περιγραφή View λειτουργεί σε iPhone, iPad, Mac, Apple Watch, Apple TV και Apple Vision Pro. Το SwiftUI προσαρμόζει τη διεπαφή στην πλατφόρμα: στο iOS — απτικές χειρονομίες, στο macOS — συντομεύσεις πληκτρολογίου, στο watchOS — κύλιση Digital Crown. Αυτό μειώνει τον χρόνο ανάπτυξης για εταιρείες που κυκλοφορούν εφαρμογές σε πολλές πλατφόρμες Apple, αλλά απαιτεί πρόσθετη διαμόρφωση για συγκεκριμένα στοιχεία κάθε πλατφόρμας.
Στο SwiftUI, κάθε οθόνη είναι μια δομή που υλοποιεί το πρωτόκολλο View με μία μόνο απαίτηση: την υπολογιζόμενη ιδιότητα body τύπου some View. Η λέξη-κλειδί some (opaque type) κρύβει τον συγκεκριμένο τύπο του view, επιτρέποντας στο SwiftUI να βελτιστοποιήσει την απόδοση. Μέσα στο body, ο προγραμματιστής συνδυάζει έτοιμα στοιχεία — Text, Image, Button, List — χρησιμοποιώντας το ViewBuilder, το οποίο συλλέγει πολλά views σε ένα.
struct GreetingView: View {
let name: String
var var body: some View {
VStack {
Text("Γεια, \(name)!")
.font(.title)
.foregroundColor(.blue)
Image(systemName: "hand.wave")
.imageScale(.large)
}
.padding()
}
}
Στο παράδειγμα, το VStack (κάθετη στοίβα) περιέχει Text και Image. Η τιμή name μεταβιβάζεται μέσω του αρχικοποιητή της δομής — έτσι λειτουργεί το DI (Dependency Injection) στο SwiftUI χωρίς εξωτερικά δοχεία DI. Κάθε modifier επιστρέφει ένα νέο view με την εφαρμοσμένη αλλαγή, χωρίς να μεταλλάσσει το πρωτότυπο. Αυτό είναι δυνατό χάρη στην αμεταβλητότητα (immutability) των value types.
ViewBuilder είναι ένα result builder, με σχόλιο @resultBuilder, που συλλέγει έως και 10 views σε ένα. Μέσα στο body μπορούν να χρησιμοποιηθούν if/else, switch και ForEach χωρίς πρόσθετα περιτυλίγματα. Το ForEach λειτουργεί με στοιχεία Identifiable — κάθε view λαμβάνει ένα μοναδικό id για σωστή κινούμενη εικόνα κατά την εισαγωγή/διαγραφή.
Στο SwiftUI, η κατάσταση καθορίζει ποιο περιεχόμενο εμφανίζεται στην οθόνη. Όταν η κατάσταση αλλάζει, το SwiftUI αναδημιουργεί το body του εξαρτημένου view και συγκρίνει το αποτέλεσμα με το προηγούμενο, εφαρμόζοντας τον αλγόριθμο diff. Για την αποθήκευση της κατάστασης χρησιμοποιούνται property wrappers — το καθένα λύνει τη δική του εργασία: τοπική κατάσταση, σύνδεση με θυγατρικό view ή εξωτερικό μοντέλο δεδομένων.
struct CounterView: View {
@State private var count = 0
var var body: some View {
VStack {
Text("Μετρητής: \(count)")
Button("Αύξηση") {
count += 1
}
}
}
}
class UserViewModel: ObservableObject {
@Published var name = ""
@Published var age = 0
}
Το @State αποθηκεύει μια τοπική απλή τιμή (Int, String, Bool) μέσα στη δομή View. Το SwiftUI μεταφέρει τη μνήμη από τη δομή σε ξεχωριστή αποθήκη — γι' αυτό η ιδιότητα με @State μπορεί να τροποποιηθεί (να μεταλλαχθεί), ακόμα κι αν το View είναι value type. Το @ObservableObject — για κλάσεις με ιδιότητες @Published, των οποίων οι αλλαγές ειδοποιούν αυτόματα το SwiftUI για την ανάγκη ανασχεδίασης.
Το @Binding δημιουργεί μια αμφίδρομη σύνδεση με την πηγή δεδομένων που βρίσκεται στο γονικό view. Ο γονέας μεταβιβάζει $variable (projected value), το παιδί διαβάζει και γράφει την τιμή μέσω binding. Αυτό επιτρέπει τη μεταφορά της εισαγωγής κειμένου ή του διακόπτη σε ξεχωριστό στοιχείο, διατηρώντας την κατάσταση στον γονέα. Χωρίς @Binding, κάθε αλλαγή θα απαιτούσε ένα callback κλείσιμο για τη μεταβίβαση της νέας τιμής προς τα πάνω.
Πριν από το iOS 16, η πλοήγηση στο SwiftUI βασιζόταν στο NavigationView — ένα ξεπερασμένο API με περίπλοκη συμπεριφορά στο iPad (split view, double column). Από το iOS 16, η Apple συνιστά το NavigationStack — μια απλοποιημένη εναλλακτική με type-safe διαδρομές. Ο προγραμματιστής ορίζει ένα enum πιθανών διαδρομών και το NavigationStack διαχειρίζεται αυτόματα τη στοίβα οθονών με υποστήριξη για deep links και επιστροφή στη ρίζα.
enum Route: Hashable {
case detail(id: Int)
case settings
}
struct ContentView: View {
var var body: some View {
NavigationStack {
List {
NavigationLink("Οθόνη λεπτομερειών",
value: Route.detail(id: 42))
NavigationLink("Ρυθμίσεις",
value: Route.settings)
}
.navigationDestination(for: Route.self) { route in
switch route {
case .detail(let id): DetailView(id: id)
case .settings: SettingsView()
}
}
}
}
}
Οι διαδρομές τύπου Route: Hashable επιτρέπουν τη χρήση οποιουδήποτε τύπου δεδομένων για τη μεταβίβαση παραμέτρων. Το navigationDestination(for:destination:) συνδέει τον τύπο διαδρομής με το view προορισμού. Πλεονέκτημα έναντι της πλοήγησης UIKit — δεν απαιτείται ανασχεδίαση κατά την προσθήκη νέας διαδρομής: αρκεί να προστεθεί ένα case στο enum και ένας χειριστής στο switch. Τα deep links υποβάλλονται σε επεξεργασία μέσω του processDeepLink στο NavigationStack.
Για προγραμματιζόμενη μετάβαση (μετά από σύνδεση, χρονοδιακόπτη ή απάντηση διακομιστή) χρησιμοποιείται @State με τον αρχικοποιητή NavigationLink: NavigationLink(isActive: $isActive). Όταν το isActive τεθεί σε true, η μετάβαση γίνεται χωρίς άγγιγμα του χρήστη. Εναλλακτικά — η σύνδεση (binding) του πίνακα $path στο NavigationStack: $path.append(Route.detail(id: 1)).
Modifier είναι μια μέθοδος που επιστρέφει ένα τροποποιημένο αντίγραφο του view. Σε αντίθεση με το UIKit, όπου η διαμόρφωση ιδιοτήτων γίνεται μέσω μετάλλαξης του υπάρχοντος view, το SwiftUI δημιουργεί μια νέα τιμή με την εφαρμοσμένη αλλαγή. Η αλυσίδα modifiers (chaining) χτίζει την τελική διεπαφή από διαδοχικούς μετασχηματισμούς: γραμματοσειρά → διάστημα → χρώμα → σκιά → χειρονομία.
Η Apple παρέχει πάνω από 200 ενσωματωμένους modifiers. Οι πιο συνηθισμένοι είναι: .font(), .foregroundColor(), .padding(), .background(), .cornerRadius(), .shadow(), .opacity(), .offset(). Η σειρά των modifiers είναι σημαντική: το .padding() πριν από το .background() χρωματίζει την περιοχή με το διάστημα, μετά — μόνο την εσωτερική περιοχή. Οι προσαρμοσμένοι modifiers δημιουργούνται μέσω του πρωτοκόλλου ViewModifier.
Οι modifiers μπορούν να εφαρμοστούν υπό όρους μέσω του τριαδικού τελεστή: .foregroundColor(isError ? .red : .primary). Για κινούμενη εικόνα χρησιμοποιείται .animation(.easeInOut, value: state) — ο modifier κινούμενης εικόνας συνδέεται με μια συγκεκριμένη ιδιότητα της κατάστασης. Όταν αλλάζει αυτή η ιδιότητα, το SwiftUI δημιουργεί κινούμενη εικόνα για τη μετάβαση μεταξύ της παλιάς και της νέας τιμής. Η κινούμενη εικόνα λειτουργεί με opacity, offset, scale, rotation, μέγεθος και χρώμα — για κάθε ιδιότητα ορίζεται ένα αντίστοιχο AnimatableParameter.
Για προσαρμοσμένες κινούμενες εικόνες είναι διαθέσιμα τα .transition (εμφάνιση/εξαφάνιση) και .matchedGeometryEffect (ομαλή μετάβαση ενός στοιχείου μεταξύ δύο δοχείων). Το τελευταίο χρησιμοποιείται για hero-εφέ σε λίστες: ένα εικονίδιο σε ένα κελί λίστας μεταμορφώνεται ομαλά σε μια μεγάλη εικόνα στην οθόνη λεπτομερειών.
Η επιλογή μεταξύ SwiftUI και UIKit είναι ένα από τα πρώτα διλήμματα ενός προγραμματιστή iOS. Και τα δύο frameworks υποστηρίζονται από την Apple, αλλά επιλύουν το έργο της δημιουργίας διεπαφής με θεμελιωδώς διαφορετικούς τρόπους: το SwiftUI declarative, το UIKit imperative. Η διαφορά εκδηλώνεται στη διαχείριση κατάστασης, πλοήγηση, απόδοση και συμβατότητα.
| Πτυχή | SwiftUI | UIKit |
|---|---|---|
| Προσέγγιση | Declarative: τι να εμφανίσει | Imperative: πώς να το κατασκευάσει |
| Κατάσταση | Property Wrappers, αυτόματη ανασχεδίαση | Χειροκίνητα: reloadData, setNeedsLayout |
| Κώδικας UI | Συμπαγής, αλυσίδες modifiers | Ογκώδης, NSCoder/Storyboard/περιορισμοί |
| Απόδοση | Υψηλή σε iOS 17+, αλγόριθμος diff | Αιχμή σε iOS 12–16, άμεσος έλεγχος |
| Ελάχιστη έκδοση | iOS 15+ (πλήρης υποστήριξη) | iOS 2+ (όλες οι εκδόσεις) |
Για νέα έργα με ελάχιστη έκδοση iOS 17, η Apple συνιστά το SwiftUI ως κύριο framework. Το UIKit παραμένει απαραίτητο για διεπαφές που απαιτούν λεπτό έλεγχο στην απόδοση (προσαρμοσμένο UICollectionViewLayout, σύνθετες σκηνές CAAnimation) ή υποστήριξη για iOS 12–14. Πολλά έργα χρησιμοποιούν υβριδική προσέγγιση: το SwiftUI μέσω UIHostingController ενσωματώνεται σε εφαρμογή UIKit, και το UIViewRepresentable επιτρέπει τη χρήση στοιχείων UIKit μέσα στην ιεραρχία SwiftUI.
Συχνές Ερωτήσεις
Ναι, μέσω UIHostingController (SwiftUI σε UIKit) και UIViewRepresentable (UIKit σε SwiftUI). Αυτή είναι μια υβριδική προσέγγιση, δημοφιλής κατά τη μετεγκατάσταση.
iOS 17 — πλήρης λειτουργικότητα: NavigationStack, Observation framework, Swift Charts. iOS 15 — ελάχιστο όριο για παραγωγή.
Η συχνότερη αιτία είναι η αλλαγή μιας @Published ιδιότητας σε νήμα παρασκηνίου. Το ObservableObject πρέπει να στέλνει αλλαγές στο main actor: @MainActor class ViewModel.
Χρησιμοποιήστε .debounce μέσω Combine: Button.publisher(for: .tap) .debounce(for: .seconds(0.3), scheduler: RunLoop.main).
Ναι, μέσω των Gesture modifiers: DragGesture, LongPressGesture, MagnificationGesture, RotationGesture. Συνδυάστε τα μέσω .simultaneousGesture() και .sequenced().
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης