Published on

Netflix kloni (4-qism): skroll offset va dinamik header

Authors

Skrollni kuzatish (OnScrollChanged)

Netflixda eng qiziq effektlardan biri shundaki, siz kinolar ro'yxatini pastga qarab o'qishni boshlasangiz (ya'ni tepaga qarab skroll qilsangiz), tepadagi Kategoriyalar paneli sekin tepaga chiqib yo'qoladi, Navigatsiya paneli esa qorayadi.

Buni qilish uchun biz ekran aynan necha pikselga surilayotganini (offset.y) bilishimiz kerak. Buning uchun SwiftfulUI paketidagi tayyor ScrollViewWithOnScrollChanged dan foydalanamiz:

@State private var scrollViewOffset: CGFloat = 0

// Oyna ichida:
ScrollViewWithOnScrollChanged(.vertical, showsIndicators: false) { offset in
    // Skroll o'zgarishini ushlab olish
    self.scrollViewOffset = min(0, offset.y) // Faqat tepaga skroll qilingandagini olamiz
} content: {
    // Asosiy kontent...
}

1. Kategoriyalarni yo'qotish (Transition)

Ekranni biroz, ya'ni -20 pikseldan ko'proq sursak, Kategoriyalar barini tepaga qarab yashiramiz:

if scrollViewOffset > -20 {
    NetflixFilterBarView(...)
        .transition(.move(edge: .top).combined(with: .opacity))
}

Ushbu transition tufayli u shunchaki yo'qolib qolmaydi, balki bir vaqtning o'zida ham tepaga chiqib ketadi (move), ham shaffof bo'lib yo'qoladi (opacity).

2. Navigatsiya orqa fonini qoraytirish (Material Effect)

Skroll yanada chuqurlashsa (masalan -70 pikseldan oshsa), Header ning orqasidan qop-qora emas, balki "Oyna" (Glassmorphism / Material) effekti bilan orqa fon tushadi:

if scrollViewOffset < -70 {
    Rectangle()
        .fill(Color.clear)
        .background(.ultraThinMaterial) // Orqasini xira oynadek qilib ko'rsatadi
        .brightness(-0.2) // Oynani biroz qoraytiramiz
        .ignoresSafeArea()
}

3. Orqa fon gradientining dinamik harakati

Kino sahnamiz (Hero cell) orqasida aslida katta qizil va kulrang gradient bor. Uni skrollga qarab qisqartirib boramiz:

private var backgroundGradientLayer: some View {
    ZStack {
        // ... Gradient ranglari ...
    }
    // Gradient balandligi skrollga mos ravishda kamayadi
    .frame(maxHeight: max(10, 400 + (scrollViewOffset * 0.75)))
    // -250 dan o'tgandan so'ng butunlay yo'qoladi
    .opacity(scrollViewOffset < -250 ? 0 : 1)
    .animation(.easeInOut, value: scrollViewOffset)
}

Arxitekturani tozalash

Biz Netflix oynasida juda ko'p narsa yozdik. Agar kodlarni to'g'ri bo'lmasak, ularni o'qish imkonsiz bo'lib qoladi. Yaxshi dasturchi sifatida barcha qatlamlarni toza strukturalab chiqamiz:

var body: some View {
    ZStack(alignment: .top) {
        // 1. Eng orqa fon
        backgroundGradientLayer

        // 2. Skroll qilinadigan ro'yxatlar
        scrollViewLayer

        // 3. Eng ustidagi doimiy Header (Tepa qism)
        fullHeaderWithFilters
    }
}

Mana shu tarzda kod yozish ZStack qanday ishlashini va loyihaning bo'limlarini osongina ajratib olishni o'rgatadi. Boshqa dasturchi bu kodni ko'rsa, darhol tushuna oladi.

Keyingi qismda biz biron filmni bosganda pastdan chiroyli ochiladigan Karta (Details Sheet) ni tayyorlashga o'tamiz.

Buy mea coffee