List — τι είναι, το στοιχείο λίστας στο SwiftUI

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-06-25 Χρόνος ανάγνωσης: 7 λεπ

List — είναι ένα View κοντέινερ στο SwiftUI για την εμφάνιση δεδομένων με τη μορφή κάθετα κυλιόμενης λίστας, ανάλογο του UITableView στο UIKit. Σύμφωνα με το Apple Developer Documentation, 2024, το List υποστηρίζει στατικές και δυναμικές ενότητες, ενέργειες σύρσης, μεταφορά γραμμών και pull-to-refresh. Σε αντίθεση με το UITableView, το List χρησιμοποιεί δηλωτικό API βασισμένο στο SwiftUI και το ForEach, διαχειριζόμενο αυτόματα την επαναχρησιμοποίηση κελιών και την απόδοση για μεγάλο αριθμό γραμμών.

Βασικά Σημεία

  • List — κοντέινερ για κυλιόμενη λίστα δεδομένων στο SwiftUI
  • ForEach — ο κύριος τρόπος δυναμικής εμφάνισης δεδομένων στο List
  • Ενότητες — Section View για ομαδοποίηση γραμμών με επικεφαλίδες
  • Ενέργειες σύρσης — swipeActions για iOS 15+
  • Pull-to-refresh — .refreshable για iOS 15+

Τι είναι το List στο SwiftUI;

List — είναι ένα View που εμφανίζει μια ακολουθία στοιχείων σε μια κάθετα κυλιόμενη λίστα. Εμφανίστηκε στο iOS 13 μαζί με το SwiftUI και είναι ο κύριος τρόπος εμφάνισης λιστών δεδομένων, αντικαθιστώντας το UITableView από το UIKit. Το List διαχειρίζεται αυτόματα την επαναχρησιμοποίηση κελιών, την κύλιση και την απόδοση.

Το List χρησιμοποιεί lazy-loading: τα κελιά δημιουργούνται κατά την κύλιση, όχι όλα ταυτόχρονα. Αυτό το διακρίνει από το VStack με ForEach μέσα στο ScrollView, όπου όλα τα κελιά δημιουργούνται κατά την απόδοση. Το List παρέχει επίσης ενσωματωμένη υποστήριξη για ενέργειες σύρσης, pull-to-refresh, επεξεργασία (διαγραφή/μεταφορά) και επιλογή γραμμών.

Σύμφωνα με το Apple WWDC 2021 (Session 10072), το List στο iOS 15+ έλαβε σημαντικές βελτιώσεις απόδοσης χάρη σε έναν νέο μηχανισμό diffing σε επίπεδο συλλογών. Αυτό κατέστησε το List πιο αποδοτικό κατά την ενημέρωση δεδομένων, ειδικά για λίστες με εκατοντάδες γραμμές.

List vs ScrollView + VStack

Οι προγραμματιστές συχνά επιλέγουν μεταξύ List και ScrollView με VStack για την εμφάνιση ενός συνόλου Views. Η βασική διαφορά: το List χρησιμοποιεί επαναχρησιμοποίηση κελιών (όπως το UITableView), ενώ το ScrollView + VStack δημιουργεί όλα τα Views ταυτόχρονα. Για λίστες με σταθερό αριθμό στοιχείων (έως 20), η διαφορά είναι αμελητέα. Για δυναμικές λίστες με 50+ γραμμές, το List είναι προτιμότερο από πλευράς απόδοσης.

Στατικές και δυναμικές λίστες

Στατική List — είναι μια λίστα με σταθερό αριθμό γραμμών, που ορίζονται απευθείας στο σώμα του List. Χρησιμοποιείται για μενού, ρυθμίσεις και φόρμες με γνωστό σύνολο στοιχείων. Κάθε γραμμή δηλώνεται ρητά, χωρίς βρόχους ή ForEach.

swift
// Στατική λίστα (για μενού και ρυθμίσεις)
List {
    Text("Προφίλ")
    Text("Ρυθμίσεις")
    Text("Σχετικά")
}

// Δυναμική λίστα (για δεδομένα)
struct UserList: View {
    let users: [User]

    var body: some View {
        List(users) { user in
            HStack {
                Text(user.name)
                Text(user.role)
                    .foregroundColor(.secondary)
            }
        }
    }
}

Δυναμική List χρησιμοποιεί τον αρχικοποιητή List(data:rowContent:) ή το ForWithin στο σώμα του List. Η πρώτη επιλογή είναι βολική όταν κάθε γραμμή αντιστοιχεί σε ένα στοιχείο δεδομένων. Η δεύτερη — όταν υπάρχουν ενότητες ή πρόσθετα στοιχεία μεταξύ των δεδομένων.

Αναγνώριση (Identifiable): Για δυναμικές λίστες, τα στοιχεία δεδομένων πρέπει να συμμορφώνονται με το πρωτόκολλο Identifiable ή στην πλειάδα data:id πρέπει να καθοριστεί KeyPath σε ένα μοναδικό αναγνωριστικό. Το SwiftUI χρησιμοποιεί αναγνωριστικά για την παρακολούθηση αλλαγών: προσθήκη, διαγραφή και μετακίνηση γραμμών.

Ενότητες και ομαδοποίηση δεδομένων

Section — είναι ένα View για την ομαδοποίηση γραμμών στο List με επικεφαλίδα και προαιρετικό υποσέλιδο. Το Section δέχεται header και footer ως ViewBuilder, επιτρέποντας τη χρήση όχι μόνο κειμένου, αλλά και προσαρμοσμένων Views για τις επικεφαλίδες ενοτήτων.

swift
struct SettingsView: View {
    var body: some View {
        List {
            Section(header: Text("Λογαριασμός")) {
                Text("Όνομα")
                Text("Email")
            }
            Section(header: Text("Ειδοποιήσεις")) {
                Toggle("Push", isOn: $pushEnabled)
                Toggle("Email", isOn: $emailEnabled)
            }
        }
        .listStyle(.insetGrouped)
    }
}

// Δυναμικές ενότητες με ForEach
List {
    ForEach(groupedData.keys.sorted(), id: \.self) { key in
        Section(header: Text(key)) {
            ForEach(groupedData[key]!) { item in
                Text(item.title)
            }
        }
    }
}

Στυλ List: Το SwiftUI παρέχει πολλά ενσωματωμένα στυλ μέσω του τροποποιητή .listStyle(). .insetGrouped — τυπικό για iOS Settings, .plain — μινιμαλιστικό, .inset — με εσοχές, .sidebar — για Sidebar στο iPad.

Σύμφωνα με το SwiftUI Cookbook (2024), το Section με δυναμικές ενότητες και ForEach μέσα είναι ένα τυπικό μοτίβο για ομαδοποίηση δεδομένων σε εφαρμογές με πολύπλοκη δομή. Βασικός κανόνας: μην τοποθετείτε Section μέσα σε Section και μη χρησιμοποιείτε τον αρχικοποιητή List(data:) μαζί με Section — χρησιμοποιήστε το ForEach μέσα στο σώμα του List.

Ενέργειες σύρσης και pull-to-refresh

.swipeActions(edge:allowsFullSwipe:content:) — τροποποιητής για iOS 15+ που προσθέτει ενέργειες σύρσης στις γραμμές του List. Επιτρέπει την εμφάνιση κουμπιών κατά το σύρσιμο προς τα αριστερά (προεπιλογή) ή προς τα δεξιά, με διαφορετικά χρώματα και ρόλους (destructive, cancel).

swift
struct TaskList: View {
    @Binding var tasks: [Task]

    var body: some View {
        List {
            ForEach($tasks) { $task in
                Text(task.title)
                    .swipeActions(edge: .trailing) {
                        Button("Διαγραφή", role: .destructive) {
                            tasks.removeAll { $0.id == task.id }
                        }
                    }
                    .swipeActions(edge: .leading) {
                        Button(task.isDone ? "Αναίρεση" : "Ολοκληρώθηκε") {
                            task.isDone.toggle()
                        }
                        .tint(.green)
                    }
            }
        }
        .refreshable {
            // Ασύγχρονη φόρτωση δεδομένων
            await loadTasks()
        }
    }
}

.refreshable — τροποποιητής για iOS 15+ που προσθέτει pull-to-refresh. Δέχεται ένα ασύγχρονο closure (async) που εκτελείται όταν ο χρήστης τραβάει τη λίστα προς τα κάτω. Το SwiftUI εμφανίζει αυτόματα την ένδειξη φόρτωσης. Μετά την ολοκλήρωση της λειτουργίας, η ένδειξη κρύβεται.

.onDelete και .onMove — τροποποιητές για iOS 13+ που προσθέτουν υποστήριξη για διαγραφή και μετακίνηση γραμμών. Για να τα χρησιμοποιήσετε, τυλίξτε τα δεδομένα σε ForEach με Binding ή μεταβιβάστε closures μέσω .onDelete(perform:) στο List ή στο ForEach.

Απόδοση List και βελτιστοποίηση

Η απόδοση του List εξαρτάται από τον αριθμό των γραμμών, την πολυπλοκότητα κάθε κελιού και τη συχνότητα ενημερώσεων δεδομένων. Το SwiftUI χρησιμοποιεί lazy-loading και επαναχρησιμοποίηση κελιών (παρόμοια με το UITableView.dequeueReusableCell), αλλά πρόσθετες βελτιστοποιήσεις μπορεί να χρειαστούν για λίστες με 500+ γραμμές.

ΒελτιστοποίησηΠεριγραφήΈκδοση iOS
IdentifiableΜοναδικό ID για κάθε στοιχείοiOS 13+
EquatableViewΑποφεύγει την επαναπόδοση σε ίσα δεδομέναiOS 13+
id(_:)Αναγκαστική αναδημιουργία View κατά αλλαγή IDiOS 13+
.equatable()Αυστηρή σύγκριση βάσει EquatableiOS 15+
Diffable dataΑυτόματο diff σε αλλαγέςiOS 15+

Πρόβλημα 1: συχνές ενημερώσεις. Εάν τα δεδομένα στη λίστα ενημερώνονται συχνά (π.χ. κάθε δευτερόλεπτο), το List μπορεί να επαναποδίδει τα ορατά κελιά σε κάθε αλλαγή κατάστασης. Λύση: χρησιμοποιήστε δομές (value types) για δεδομένα — το SwiftUI τα συγκρίνει βάσει τιμής και επαναποδίδει μόνο τις αλλαγμένες γραμμές.

Πρόβλημα 2: βαριά κελιά. Εάν κάθε γραμμή περιέχει πολύπλοκη ιεραρχία Views, εικόνες και κινούμενα σχέδια, η κύλιση μπορεί να είναι αργή. Λύση: μεταφέρετε τα κελιά σε ξεχωριστά Views, χρησιμοποιήστε EquatableView για να αποτρέψετε περιττές επαναποδόσεις. Σύμφωνα με το SwiftUI Lab (2024), η διάσπαση μιας πολύπλοκης γραμμής σε υποσυστατικά μειώνει τον χρόνο απόδοσης κατά 30–50%.

Πρόβλημα 3: μεγάλος αριθμός γραμμών. Σε 1000+ γραμμές, το List εξακολουθεί να λειτουργεί αποδοτικά χάρη στο lazy-loading, αλλά η αρχική φόρτωση μπορεί να επιβραδυνθεί λόγω υπολογισμού διάταξης. Λύση: χρησιμοποιήστε LazyVStack μόνο για λίστες με ομοιογενείς γραμμές όπου δεν χρειάζονται οι λειτουργίες του List (σύρσιμο, ενότητες). Για πλήρως λειτουργικές λίστες, το List παραμένει η καλύτερη επιλογή.

Συχνές Ερωτήσεις

Τι είναι το List στο SwiftUI;

List — ένα View κοντέινερ για την εμφάνιση κυλιόμενης λίστας δεδομένων στο SwiftUI. Ανάλογο του UITableView στο UIKit με δηλωτικό API. Υποστηρίζει ενότητες, ενέργειες σύρσης, pull-to-refresh, επεξεργασία και προσαρμογή μέσω .listStyle().

Πώς διαφέρει το List από το ScrollView + VStack;

Το List χρησιμοποιεί lazy-loading και επαναχρησιμοποίηση κελιών — τα κελιά δημιουργούνται κατά την κύλιση. Το ScrollView + VStack δημιουργεί όλα τα Views ταυτόχρονα. Για λίστες με 50+ γραμμές, το List είναι προτιμότερο. Για σταθερά μικρά σύνολα (έως 20 στοιχεία), η διαφορά είναι αμελητέα.

Πώς προσθέτω pull-to-refresh στο List;

Χρησιμοποιήστε τον τροποποιητή .refreshable (iOS 15+). Μεταβιβάστε ένα ασύγχρονο closure με λογική ενημέρωσης δεδομένων. Το SwiftUI εμφανίζει αυτόματα την ένδειξη φόρτωσης και την κρύβει μετά την ολοκλήρωση της ασύγχρονης λειτουργίας.

Πώς ομαδοποιώ γραμμές στο List;

Χρησιμοποιήστε Section View με επικεφαλίδα και προαιρετικό υποσέλιδο. Τοποθετήστε τις γραμμές λίστας μέσα στο Section. Για δυναμικές ενότητες, χρησιμοποιήστε ForEach με groupedData. Το στυλ λίστας διαμορφώνεται μέσω .listStyle(.insetGrouped) για εμφάνιση παρόμοια με iOS.

Πώς επιταχύνω το List με μεγάλο αριθμό γραμμών;

Χρησιμοποιήστε δομές (value types) για δεδομένα, μεταφέρετε πολύπλοκα κελιά σε ξεχωριστά Views με EquatableView, αποφύγετε συχνές ενημερώσεις κατάστασης σε κάθε γραμμή. Για λίστες με 1000+ γραμμές, εξετάστε το LazyVStack εάν δεν χρειάζονται οι λειτουργίες του List.

Σύνοψη

  • List — κοντέινερ για κυλιόμενη λίστα με lazy-loading και επαναχρησιμοποίηση κελιών
  • ForEach — ο κύριος τρόπος δυναμικής εμφάνισης δεδομένων στο List
  • Section — ομαδοποίηση γραμμών με επικεφαλίδες και υποσέλιδο
  • swipeActions — ενέργειες σύρσης για iOS 15+
  • refreshable — pull-to-refresh για iOS 15+
  • Στυλ — insetGrouped, plain, inset, sidebar μέσω .listStyle()
  • Απόδοση — χρησιμοποιήστε Identifiable, EquatableView και value types

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

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

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