Published on

Bumble kloni (4-qism): Chat ro'yxati va doiraviy animatsiyalar

Authors

Yangi oyna: Xabarlar (Chat) ekrani

Bumble ilovasining yana bir ajralib turadigan qismi bu xabarlar o'yasi bo'lib, u yerda Match bo'lgan odamlar bilan gaplashish uchun berilgan vaqt qancha qolgani profil rasmi atrofidagi sariq halqa bilan ko'rsatiladi.

Keling avval ushbu murakkab profil rasmini alohida komponent sifatida (BumbleProfileImageCell) yaratib olaylik.

1. Doiraviy vaqt indikatori (Profile Image Cell)

Bu komponentda 3 ta qatlam bor:

  1. Kulrang to'liq halqa (Orqa fon)
  2. Sariq chala halqa (Qolgan vaqtni ko'rsatadi, masalan 50%)
  3. Profil rasmining o'zi

Sariq chala halqani yaratish uchun SwiftUI ning eng zo'r modifikatorlaridan biri — .trim (kesish) dan foydalanamiz.

import SwiftUI

struct BumbleProfileImageCell: View {
    var imageName: String = "https://picsum.photos/600/600"
    var percentageRemaining: Double = 0.5 // Qolgan vaqt (Masalan, 50%)
    var hasNewMessage: Bool = true // Yangi xabar bormi?

    var body: some View {
        ZStack {
            // Orqa kulrang halqa
            Circle()
                .stroke(Color.bumbleGray, lineWidth: 2)

            // Sariq vaqt halqasi
            Circle()
                .trim(from: 0, to: percentageRemaining) // Faqat qolgan qismini chizadi
                .stroke(Color.bumbleYellow, lineWidth: 4)
                .rotationEffect(Angle(degrees: -90)) // Tepadan boshlanishi uchun burib qo'yamiz
                .scaleEffect(x: -1, y: 1, anchor: .center) // Soat miliga qarshi (chapga) aylanishi uchun invert qilamiz

            // Asosiy rasm
            ImageLoaderView(urlString: imageName)
                .clipShape(Circle())
                .padding(5) // Rasm va halqalar orasida joy tashlash
        }
        .frame(width: 75, height: 75)
        .overlay(
            // Yangi xabar uchun kichkina sariq nuqta
            ZStack {
                if hasNewMessage {
                    Circle()
                        .fill(Color.bumbleWhite) // Oq hoshiya

                    Circle()
                        .fill(Color.bumbleYellow) // Asosiy sariq yadro
                        .padding(4)
                }
            }
            .frame(width: 24, height: 24)
            .offset(x: 2, y: 2)
            , alignment: .bottomTrailing // O'ng tomon eng pastiga yopishtiramiz
        )
    }
}

Ajoyib hiyla: Odatda .trim modifikatori aylanishni o'ng tomon (soat 3 pozitsiyasi) dan boshlaydi va o'ngga qarab aylanadi. Bumble'da esa u tepadandan (soat 12) boshlanib, chapga qarab yuradi. Buni to'g'irlash uchun biz avval halqani .rotationEffect bilan -90 gradusga (tepaga) burdik va .scaleEffect(x: -1) yordamida oyna teskari tasviriga (X o'qi bo'ylab invertatsiya) o'zgartirdik.

2. Chat ro'yxati katakchasi (Chat Preview Cell)

Tepadagi tayyor profil rasmini olib, endi uni to'liq bitta chat qatoriga (Ismi va xabari bor katakcha) qo'yamiz:

import SwiftUI

struct BumbleChatPreviewCell: View {
    var imageName: String = "https://picsum.photos/600/600"
    var percentageRemaining: Double = 0.5
    var hasNewMessage: Bool = true
    var userName: String = "Nick"
    var lastChatMessage: String? = "This is the last message"
    var isYourMove: Bool = true

    var body: some View {
        HStack(spacing: 16) {
            BumbleProfileImageCell(
                imageName: imageName,
                percentageRemaining: percentageRemaining,
                hasNewMessage: hasNewMessage
            )

            VStack(alignment: .leading, spacing: 2) {
                HStack(spacing: 0) {
                    Text(userName)
                        .font(.headline)
                        .foregroundColor(.bumbleBlack)
                        .frame(maxWidth: .infinity, alignment: .leading)

                    if isYourMove {
                        Text("YOUR MOVE")
                            .font(.caption2)
                            .bold()
                            .padding(.vertical, 4)
                            .padding(.horizontal, 6)
                            .background(Color.bumbleYellow)
                            .cornerRadius(32)
                    }
                }

                if let lastChatMessage {
                    Text(lastChatMessage)
                        .font(.subheadline)
                        .foregroundColor(.bumbleGray)
                        .padding(.trailing, 16)
                        .lineLimit(1) // Xabar uzun bo'lsa qirqib tashlaydi
                }
            }
            .lineLimit(1)
        }
    }
}

Bizda endi chat ekrani uchun tayyor ro'yxat qatori mavjud. Keyingi yakuniy darsimizda bularning barchasini to'liq bitta yaxlit "Chats" ekraniga yig'amiz.

Buy mea coffee