Published on

Bumble kloni (3-qism): Swipe ishoralari (Gestures) va mantiq

Authors

Foydalanuvchilar ro'yxati ustida ishlash

Bumble asosiy oynasida biz birinchi navbatda foydalanuvchilar (users) ni ma'lumotlar bazasidan olamiz. Lekin, eng katta xatolaridan biri: barcha foydalanuvchilarni bitta ZStack ichiga birdaniga tashlashdir. Agar yuzlab odamlar bo'lsa, ekran shu zahoti qotib qoladi.

To'g'ri yechim: Faqatgina joriy (current), keyingi (next) va oldingi (previous) qatorlarni ekranda chizish. Qolganlarini xotirada ushlab turamiz.

1. Kartalarni indekslash va Z-Index

Buning uchun biz allUsers ni .enumerated() yordamida aylanib chiqamiz va qaysi birining indeksi joriy indeksga yaqin bo'lsa, o'shalarni chizamiz.

Shuningdek, z-index larni shunday hisoblash kerakki, 0-indeksdagi foydalanuvchi eng tepada, 1-indeksdagisi uning tagida tursin:

@State private var selectedIndex: Int = 0

// ZStack ichida:
ForEach(Array(allUsers.enumerated()), id: \.offset) { index, user in
    let isCurrent = selectedIndex == index
    let isNext = selectedIndex + 1 == index
    let isPrevious = selectedIndex - 1 == index

    if isCurrent || isNext || isPrevious {
        BumbleCardView(user: user)
            .zIndex(Double(allUsers.count - index)) // O'ziga xos teskari z-index
            // ...
    }
}

2. Drag Gesture (Surish ishoralari)

Kartalarni ekranda surish uchun biz withDragGesture modifikatorini ishlatamiz. Foydalanuvchi barmoqni siljitganda (onChanged), kartaning x pozitsiyasini o'zgartiramiz. Barmoqni qo'yib yuborganda (onEnded) esa, agar surish masofasi 50 pikseldan oshgan bo'lsa, uni yo'q qilamiz, yo'qsa joyiga qaytaramiz (Bouncing effect).

@State private var cardOffsets: [String: Bool] = [:] // Qaysi ID qayoqqa ketgani haqida

// ... (BumbleCardView ostida)
.offset(x: cardOffsets[user.id] == nil ? 0 : (cardOffsets[user.id]! ? 900 : -900))
.withDragGesture(
    onChanged: { dragOffset in
        // Barmoq harakati...
    },
    onEnded: { dragOffset in
        if dragOffset.width < -50 {
            // Chapga surildi (Dislike)
            userDidSelect(index: index, isLike: false)
        } else if dragOffset.width > 50 {
            // O'ngga surildi (Like)
            userDidSelect(index: index, isLike: true)
        }
    }
)

Surish tugaganda userDidSelect funksiyasi ishga tushadi va tanlangan selectedIndex ni bittaga oshiradi (Keyingi odamga o'tadi).

3. Dinamik Overlay indikatorlar (X va ✔️)

Siz kartani chapga yoki o'ngga surayotganingizda chekkadan animatsiya bilan paydo bo'ladigan X va Check belgilarini qanday qilamiz? Buni barmoq qanchalik uzoqqa tortilganiga (offset) qarab bog'lashimiz mumkin:

// Checkmark belgisi qismi uchun
Circle()
    .fill(Color.bumbleGray.opacity(0.4))
    .overlay(
        Image(systemName: "checkmark")
            .font(.title)
            .fontWeight(.semibold)
    )
    // Offset -150 dan oshib ketmasligini ta'minlash uchun minimum olinadi
    .offset(x: max(currentSwipeOffset, -150))
    // Surish 100 dan oshsa sekin kattalasha boshlaydi
    .scaleEffect(abs(currentSwipeOffset) > 100 ? 1.5 : 1.0)

Bunday chiroyli xususiyatlar ilovani "arzon" emas, aksincha yuqori sifatli va professional qilib ko'rsatadi.

Keyingi qismda foydalanuvchilar kartasining ichida turib ularning barcha rasmlarini ekranni bosish orqali ko'rishni o'rganamiz!

Buy mea coffee