Published on

SwiftUI-da List — elementlarni qo'shish, tahrirlash, ko'chirish va o'chirish

Authors

Bu videoda biz List haqida gaplashamiz. List — bu VStack-ga o'xshaydi, lekin undan farqli ravishda elementlarni o'chirish, ko'chirish va tahrirlash imkoniyatlarini juda oson beradi. Ilovalarda ro'yxat ko'rsatish kerak bo'lganda List eng qulay tanlov.


Oddiy List yaratish

struct ListBootcamp: View {

    @State var fruits: [String] = [
        "Olma",
        "Apelsin",
        "Banan",
        "Shaftoli",
    ]

    var body: some View {
        List {
            ForEach(fruits, id: \.self) { fruit in
                Text(fruit.capitalized)
            }
        }
    }
}

List har bir element orasiga avtomatik chiziq qo'shadi. id: \.self — har bir elementni o'zini ID sifatida ishlatish.


Section — bo'limlar qo'shish

List {
    Section(header: Text("Mevalar")) {
        ForEach(fruits, id: \.self) { fruit in
            Text(fruit.capitalized)
        }
    }
}

onDelete — swipe bilan o'chirish

Bitta .onDelete qo'shish kifoya — swipe-to-delete avtomatik paydo bo'ladi:

List {
    Section(header: Text("Mevalar")) {
        ForEach(fruits, id: \.self) { fruit in
            Text(fruit.capitalized)
        }
        .onDelete(perform: delete)
    }
}

// Funksiyani body-dan tashqariga chiqarish — toza kod
func delete(at indexSet: IndexSet) {
    fruits.remove(atOffsets: indexSet)
}

Qisqa yozuv — agar funksiya parametrlari onDelete bilan mos bo'lsa, to'g'ridan-to'g'ri uzatish mumkin:

.onDelete(perform: delete)
// Bu xuddi shunday ishlaydi:
// .onDelete { indexSet in delete(at: indexSet) }

onMove — elementlarni ko'chirish

List {
    Section(header: Text("Mevalar")) {
        ForEach(fruits, id: \.self) { fruit in
            Text(fruit.capitalized)
        }
        .onDelete(perform: delete)
        .onMove(perform: move)
    }
}

func delete(at indexSet: IndexSet) {
    fruits.remove(atOffsets: indexSet)
}

func move(from indices: IndexSet, to newOffset: Int) {
    fruits.move(fromOffsets: indices, toOffset: newOffset)
}

EditButton — bu SwiftUI-ning tayyor tugmasi. Bosilganda tahrirlash rejimi yonadi: o'chirish tugmalari va ko'chirish tutqichlari paydo bo'ladi.

struct ListBootcamp: View {

    @State var fruits: [String] = ["Olma", "Apelsin", "Banan", "Shaftoli"]
    @State var veggies: [String] = ["Pomidor", "Kartoshka", "Sabzi"]

    var body: some View {
        NavigationView {
            List {
                Section(header: Text("Mevalar")) {
                    ForEach(fruits, id: \.self) { fruit in
                        Text(fruit.capitalized)
                    }
                    .onDelete(perform: delete)
                    .onMove(perform: move)
                }

                Section(header: Text("Sabzavotlar")) {
                    ForEach(veggies, id: \.self) { veggie in
                        Text(veggie.capitalized)
                    }
                }
            }
            .navigationTitle("Oziq-ovqat ro'yxati")
            .navigationBarItems(
                leading: EditButton(),   // tayyor tahrirlash tugmasi
                trailing: addButton      // o'zimiz yaratgan qo'shish tugmasi
            )
        }
    }

    // Tugmani alohida computed variable sifatida ajratish — body toza qoladi
    var addButton: some View {
        Button("Qo'shish") {
            add()
        }
    }

    func delete(at indexSet: IndexSet) {
        fruits.remove(atOffsets: indexSet)
    }

    func move(from indices: IndexSet, to newOffset: Int) {
        fruits.move(fromOffsets: indices, toOffset: newOffset)
    }

    func add() {
        fruits.append("Kokos")
    }
}

List ko'rinish uslublari — listStyle

// Standart (default)
.listStyle(DefaultListStyle())

// Guruhli — qatorlar ekranning chetiga yetadi
.listStyle(GroupedListStyle())

// Yaxlitlangan guruhli — elementlar "pufakcha" ichida
.listStyle(InsetGroupedListStyle())  // Ko'p ilovalarda ishlatiladigan uslub

// Yon panel — iPad-da boshqacha ko'rinadi
.listStyle(SidebarListStyle())

Eslatma: List uslublari qurilmaga qarab moslashadi. iPhone-da yaxshi ko'rinsa ham, iPad-da boshqacha bo'lishi mumkin — ilovangizni barcha qurilmalarda sinab ko'ring.


List elementining fon rangini o'zgartirish

Oddiy .background List ichida to'liq ishlamaydi. Buning o'rniga .listRowBackground ishlating:

ForEach(fruits, id: \.self) { fruit in
    Text(fruit.capitalized)
        .foregroundColor(.white)
        .padding(.vertical)
        // ❌ Bu to'liq ishlamaydi:
        // .background(Color.pink)

        // ✅ Bu to'g'ri usul:
        .listRowBackground(Color.pink)
}

Section sarlavhasini moslash

Section sarlavhasi faqat matn bo'lishi shart emas — istalgan view qo'yish mumkin:

Section(header:
    HStack {
        Image(systemName: "flame.fill")
        Text("Mevalar")
    }
    .font(.headline)
    .foregroundColor(.orange)
) {
    // ...
}

Accent rangini o'zgartirish

// Butun NavigationView uchun
NavigationView { ... }
    .accentColor(.red)

// Faqat List uchun
List { ... }
    .accentColor(.purple)

To'liq kod — hammasi birgalikda

struct ListBootcamp: View {

    @State var fruits: [String] = ["Olma", "Apelsin", "Banan", "Shaftoli"]
    @State var veggies: [String] = ["Pomidor", "Kartoshka", "Sabzi"]

    var body: some View {
        NavigationView {
            List {
                Section(header:
                    HStack {
                        Image(systemName: "flame.fill")
                        Text("Mevalar")
                    }
                    .font(.headline)
                    .foregroundColor(.orange)
                ) {
                    ForEach(fruits, id: \.self) { fruit in
                        Text(fruit.capitalized)
                            .padding(.vertical)
                            .listRowBackground(Color.pink.opacity(0.3))
                    }
                    .onDelete(perform: delete)
                    .onMove(perform: move)
                }

                Section(header: Text("Sabzavotlar")) {
                    ForEach(veggies, id: \.self) { veggie in
                        Text(veggie.capitalized)
                    }
                }
            }
            .listStyle(InsetGroupedListStyle())
            .navigationTitle("Oziq-ovqat ro'yxati")
            .navigationBarItems(
                leading: EditButton(),
                trailing: addButton
            )
        }
    }

    var addButton: some View {
        Button("Qo'shish") {
            add()
        }
    }

    func delete(at indexSet: IndexSet) {
        fruits.remove(atOffsets: indexSet)
    }

    func move(from indices: IndexSet, to newOffset: Int) {
        fruits.move(fromOffsets: indices, toOffset: newOffset)
    }

    func add() {
        fruits.append("Kokos")
    }
}

Xulosa — List vs VStack

XususiyatVStackList
Swipe-to-deleteQo'lda kodlash kerak.onDelete — bir qator
Ko'chirishQo'lda kodlash kerak.onMove — bir qator
EditButtonYo'qTayyor
SectionYo'qTayyor
Ko'rinishOddiyQurilmaga moslashuvchi

Agar foydalanuvchi o'chirishi yoki tartibini o'zgartirishi kerak bo'lgan ro'yxat yaratayotgan bo'lsangiz — albatta List ishlating. Aks holda oddiy VStack ham yetarli.

Rahmat, men Nick, bu Swiftful Thinking va keyingi videoda ko'rishguncha!

Buy mea coffee