Листа — шта је то, компонента листе у 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-ом за приказ скупа View-ова. Кључна разлика: List користи поновну употребу ћелија (као UITableView), а ScrollView + VStack ствара све View-ове одједном. За листе са фиксним бројем елемената (до 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:) или ForEach унутар тела List-а. Прва опција је згодна када сваки ред одговара једном елементу података. Друга — када постоје секције или додатни елементи између података.

Идентификација (Identifiable): За динамичке листе елементи података морају бити у складу са протоколом Identifiable или у туплу data:id треба навести KeyPath до јединственог идентификатора. SwiftUI користи идентификаторе за праћење промена: додавања, брисања и премештања редова.

Секције и груписање података

Section — View за груписање редова у List-у са заглављем и опционим footer-ом. Section прихвата header и footer као ViewBuilder, омогућавајући коришћење не само текста, већ и прилагођених View-ова за заглавља секција.

swift
struct SettingsView: View {
    var body: some View {
        List {
            Section(header: Text("Налог")) {
                Text("Име")
                Text("Е-пошта")
            }
            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. Прихвата асинхроно затварање (async) које се извршава када корисник повуче листу надоле. SwiftUI аутоматски приказује индикатор учитавања. Након завршетка операције индикатор се скрива.

.onDelete и .onMove — модификатори за iOS 13+ који додају подршку за брисање и премештање редова. Да бисте их користили, умотајте податке у ForEach са Binding-ом или проследите затварања кроз .onDelete(perform:) на List или ForEach.

Перформансе List-а и оптимизација

Перформансе List-а зависе од броја редова, сложености сваке ћелије и учесталости ажурирања података. SwiftUI користи lazy-loading и поновну употребу ћелија (слично UITableView.dequeueReusableCell), али додатне оптимизације могу бити потребне за листе са 500+ редова.

ОптимизацијаОписiOS верзија
IdentifiableЈединствени ID за сваки елементiOS 13+
EquatableViewИзбегава прецртавање при једнаким подацимаiOS 13+
id(_:)Принудно поновно стварање View-а при промени ID-аiOS 13+
.equatable()Поређење строго по EquatableiOS 15+
Diffable dataАутоматски diff при променамаiOS 15+

Проблем 1: честа ажурирања. Ако се подаци у листи често ажурирају (нпр. сваке секунде), List може прецртавати видљиве ћелије при свакој промени стања. Решење: користите структуре (value types) за податке — SwiftUI их упоређује по вредности и прецртава само измењене редове.

Проблем 2: тешке ћелије. Ако сваки ред садржи сложену хијерархију View-ова, слике и анимације, померање може бити споро. Решење: издвојите ћелије у засебне View-ове, користите EquatableView за спречавање непотребних прецртавања. Према SwiftUI Lab (2024), подела сложеног реда на подкомпоненте смањује време рендеровања за 30–50%.

Проблем 3: велики број редова. При 1000+ редова List и даље ради ефикасно захваљујући lazy-loading-у, али почетно учитавање може успорити због израчунавања layout-а. Решење: користите LazyVStack само за листе са истоврсним редовима где нису потребне функције List-а (превлачење, секције). За потпуно функционалне листе List остаје најбољи избор.

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

Шта је List у SwiftUI?

List — контејнерско View за приказ помичне листе података у SwiftUI. Аналог UITableView-а у UIKit-у са декларативним API-јем. Подржава секције, превлачење, pull-to-refresh, уређивање и прилагођавање кроз .listStyle().

По чему се List разликује од ScrollView + VStack?

List користи lazy-loading и поновну употребу ћелија — ћелије се стварају током померања. ScrollView + VStack ствара све View-ове одједном. За листе са 50+ редова List је пожељнији. За фиксне мале скупове (до 20 елемената) разлика је занемарљива.

Како додати pull-to-refresh у List?

Користите модификатор .refreshable (iOS 15+). Проследите асинхроно затварање са логиком ажурирања података. SwiftUI аутоматски приказује индикатор учитавања и скрива га након завршетка асинхроне операције.

Како груписати редове у List-у?

Користите Section View са header-ом и опционим footer-ом. Унутар Section-а поставите редове листе. За динамичке секције користите ForEach са groupedData. Стил листе се подешава кроз .listStyle(.insetGrouped) за iOS-олики изглед.

Како убрзати List са великим бројем редова?

Користите структуре (value types) за податке, издвојите сложене ћелије у засебне View-ове са EquatableView, избегавајте честа ажурирања стања у сваком реду. За листе са 1000+ редова размотрите LazyVStack ако нису потребне функције List-а.

Закључак

  • List — контејнер за помичну листу са lazy-loading-ом и поновном употребом ћелија
  • ForEach — основни начин динамичког приказа података у List-у
  • Section — груписање редова са заглављима и footer-ом
  • swipeActions — превлачење за iOS 15+
  • refreshable — pull-to-refresh за iOS 15+
  • Стилови — insetGrouped, plain, inset, sidebar кроз .listStyle()
  • Перформансе — користите Identifiable, EquatableView и value types

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

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

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

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