- Published on
Netflix kloni (1-qism): Mikro-animatsiyalar va dizayn
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
Yangi loyiha: Netflix
Bumble va Spotify ni muvaffaqiyatli yakunlaganimizdan so'ng, navbatdagi murakkab va chiroyli ilova — Netflix ni yasashga o'tamiz. Netflix interfeysining eng katta yutug'i shundaki, unda juda ham ko'p mikro-animatsiyalar (micro-animations) mavjud. Ushbu kichik detallar ilovaga premium (juda sifatli) his bag'ishlaydi. Biz aynan shunday detallarni SwiftUI'da qanday qilib yozishni o'rganamiz.
1. Ranglar to'plami
Boshlashdan oldin Assets bo'limida yangi Netflix ranglarini qo'shib olamiz:
NetflixBlack:#000000(Mutlaqo qora)NetflixDarkGray:#3E3737NetflixDarkRed:#831010NetflixLightGray:#B3B3B3NetflixRed:#E50914(Netflix'ning o'z qizili)NetflixWhite:#FFFFFF
2. Kategoriya filtri (Filter Cell)
Netflixning asosiy oynasida eng tepada "TV Shows", "Movies", "Categories" degan tugmachalar mavjud. Agar ulardan birini tanlasangiz, tugma shakli o'zgaradi va uning yonida X belgisi paydo bo'ladi. Avvalo alohida bitta tugmachani yasab olamiz:
import SwiftUI
struct NetflixFilterCell: View {
var title: String = "Categories"
var isDropdown: Bool = true
var isSelected: Bool = false
var body: some View {
HStack(spacing: 4) {
Text(title)
if isDropdown {
Image(systemName: "chevron.down")
}
}
.padding(.horizontal, 16)
.padding(.vertical, 8)
.background(
// Tanlangan holatda orqa fon qop-qora, tanlanmagan holatda esa faqat hoshiya chiziladi
ZStack {
Capsule(style: .circular)
.fill(Color.netflixDarkGray)
.opacity(isSelected ? 1 : 0) // Sekin paydo bo'lish animatsiyasi
Capsule(style: .circular)
.stroke(lineWidth: 1)
}
)
.foregroundColor(.netflixLightGray)
}
}
Ajoyib Xususiyat: Biz bu yerda
if isSelecteddeb alohida Capsule chizmadik. U doim chizilib turibdi, faqatgina uning.opacity(ko'rinuvchanlik) xususiyatini o'zgartirmoqdamiz. Bu orqali ekran bir xolatdan ikkinchisiga o'tayotganda hechnarsa "sakrab" ketmaydi, silliq animatsiya bo'ladi.
3. Filtrlar qatori (Filter Bar) va Mikro-animatsiya
Barcha filter tugmachalarini bitta gorizontal ro'yxatga (Scroll) yig'amiz. Va eng asosiysi: biror tugma bosilsa, chap tomondan silliq animatsiya bilan X belgisi kirib keladi:
import SwiftUI
struct NetflixFilterBarView: View {
var filters: [FilterModel] = FilterModel.mockArray
var selectedFilter: FilterModel? = nil
var onFilterPressed: ((FilterModel) -> Void)? = nil
var onXMarkPressed: (() -> Void)? = nil
var body: some View {
ScrollView(.horizontal, showsIndicators: false) {
HStack {
if selectedFilter != nil {
Image(systemName: "xmark")
.padding(8)
.background(
Circle()
.stroke(lineWidth: 1)
)
.foregroundColor(.netflixLightGray)
.onTapGesture {
onXMarkPressed?()
}
// X belgisi chap tomondan silliq sirpanib kirib keladi
.transition(.move(edge: .leading))
}
ForEach(filters, id: \.self) { filter in
if selectedFilter == nil || selectedFilter == filter {
NetflixFilterCell(
title: filter.title,
isDropdown: filter.isDropdown,
isSelected: selectedFilter == filter
)
.onTapGesture {
onFilterPressed?(filter)
}
}
}
}
.padding(.horizontal, 16)
}
// Bouncy (sakrovchi) animatsiyani ulaymiz
.animation(.bouncy, value: selectedFilter)
}
}
E'tibor qiling, biz avvalgi proyektlarimizda holatni (State) ushlab turish uchun @Binding dan foydalangan edik. Netflix da esa biz Closure funksiyalaridan (onFilterPressed) foydalanmoqdamiz. Nega? Chunki @Binding bo'lsa darhol ekran o'zgarib ketadi. Ammo closure yordamida biz tugma bosilganda avval biror tekshirish qilib, masalan internetga ma'lumot jo'natib, keyin UI ni yangilash imkoniga ega bo'lamiz! Bu Real loyihalarda juda muhim arxitektura qismidir.
Keyingi qismda asosiy ekrandagi asar tizeri (Hero section) ni quramiz.