Published on

Bumble kloni (1-qism): UI elementlari va Filter animatsiyasi

Authors

Yangi loyiha: Bumble

Spotify darslarimiz yakuniga yetdi! O'ylaymanki, u yerda ko'rsatilgan ScrollView mantiqlari barchaga manzur bo'ldi. Endi navbatdagi va mutlaqo boshqacha uslubdagi ilova — Bumble ni yasashga kirishamiz.

Nega aynan Bumble? Chunki bu ilovaning asosiy funksiyasi rasmlarni o'ngga yoki chapga surish (Swipe) ga asoslangan. iOS dasturlashda ko'pchilik qiynaladigan bu mantiqni SwiftUI orqali qanday qilib oson yasash mumkinligini ushbu darslarda ko'rib chiqamiz.

1. Ranglar

Odatdagidek ishimizni loyihamizning Assets bo'limiga Bumble ga xos bo'lgan ranglarni qo'shib olishdan boshlaymiz:

  • BumbleBlack: #121212
  • BumbleGray: #535353
  • BumbleLightYellow: #FFCE00 (ochroq sariq)
  • BumbleYellow: #FFCB37
  • BumbleWhite: #FFFFFF
  • BumbleBackgroundYellow: #FFF7E1

2. Asosiy ekran va sarlavha (Header)

Avvalo BumbleHomeView nomli asosiy ekranni yaratib olamiz. Tepadagi sarlavha (Header) qismi oddiy: Chap tomonda ikkita ikonka, o'rtada Bumble so'zi, o'ng tomonda esa filter ikonkalari bor.

Ularning bari bir xil o'lchamga (Max width) ega bo'lishi va markaz buzilmasligi uchun har bir guruhga .frame(maxWidth: .infinity) hamda tegishli alignment lar beramiz.

3. Filtr animatsiyasi (Matched geometry effect)

Bumble sarlavhasining eng pastida "Everyone" va "Trending" degan tugmachalar bo'lib, ular orasida qora tagchiziq o'zgaradi. Buni BumbleFilterView deb nomlangan alohida reusable (qayta ishlatiluvchi) komponent qilamiz.

Bunda tagchiziqning bir tugmadan ikkinchi tugmaga silliq "sakrab" o'tishini ta'minlash uchun iOS dagi eng chiroyli animatsiya turlaridan biri Matched Geometry Effect dan foydalanamiz.

Bu shunday ishlaydi: bitta chiziq yo'qolib, ikkinchisi paydo bo'lganda iOS avtomatik tarzda ularni bitta obyekt deb o'ylaydi va birinchi pozitsiyadan ikkinchisiga silliq olib o'tadi.

import SwiftUI

struct BumbleFilterView: View {
    var options: [String] = ["Everyone", "Trending"]
    @Binding var selection: String
    @Namespace private var namespace // MatchedGeometryEffect uchun kerak

    var body: some View {
        HStack(alignment: .top, spacing: 32) {
            ForEach(options, id: \.self) { option in
                VStack(spacing: 8) {
                    Text(option)
                        .frame(maxWidth: .infinity)
                        .font(.subheadline)
                        .fontWeight(.medium)

                    if selection == option {
                        Rectangle()
                            .frame(height: 1.5)
                            .matchedGeometryEffect(id: "selectionLine", in: namespace) // Sehr shu yerda!
                    }
                }
                .foregroundColor(selection == option ? .bumbleBlack : .bumbleGray)
                .background(Color.black.opacity(0.001)) // Tap uchun fon
                .onTapGesture {
                    selection = option
                }
            }
        }
        .animation(.smooth, value: selection) // Tanlov o'zgarganda animatsiya ishlaydi
    }
}

Ajoyib Xususiyat (@AppStorage): BumbleHomeView da biz tanlangan filterni shunchaki @State da emas, balki @AppStorage("bumble_home_filter") da saqlab qo'yamiz. Bu orqali foydalanuvchi "Trending" bo'limini tanlab, ilovadan chiqib ketsa va qayta kirsa, filter baribir "Trending"da turgan bo'ladi!

Keyingi darsda Swipe qilinadigan maxsus "Karta" larni yasashni ko'rib chiqamiz.

Buy mea coffee