Published on

Spotify kloni (4-qism): Pleylist ekrani va Stretchy Header

Authors

Yangi Ekranga o'tamiz: Pleylist oynasi

Keling, foydalanuvchi asosiy (Home) ekrandan biror pleylistni bossa ochiladigan ikkinchi oynani yasashni boshlaymiz. Buni SpotifyPlaylistView deb nomlaymiz.

Bu ekranning eng qiziq va qiyin joyi shundaki, tepada katta rasm bor. Agar barmoqni pastga tortsangiz rasm kattalashib chuziladi (Stretchy Header), tepaga sursangiz rasm sekin yo'qolib o'rniga Navigation Bar paydo bo'ladi.

1. PlaylistHeaderCell va stretchy header

Avval Components papkamizda PlaylistHeaderCell degan fayl yaratib, tepada turuvchi katta rasmni sozlab olamiz:

import SwiftUI
import SwiftfulUI // Stretchy header uchun o'zimizning kutubxona

struct PlaylistHeaderCell: View {
    var height: CGFloat = 300
    var title: String = "Subtitle goes here"
    var subtitle: String = "Title goes here"
    var imageName: String = "https://picsum.photos/600/600"
    var shadowColor: Color = .spotifyBlack.opacity(0.8)

    var body: some View {
        Rectangle()
            .opacity(0)
            .overlay(
                ImageLoaderView(urlString: imageName)
            )
            .overlay(
                VStack(alignment: .leading, spacing: 8) {
                    Text(subtitle)
                        .font(.headline)

                    Text(title)
                        .font(.largeTitle)
                        .fontWeight(.bold)
                }
                .foregroundColor(.spotifyWhite)
                .padding(16)
                .frame(maxWidth: .infinity, alignment: .leading)
                .background(
                    LinearGradient(
                        colors: [shadowColor.opacity(0), shadowColor],
                        startPoint: .top,
                        endPoint: .bottom
                    )
                )
                , alignment: .bottomLeading
            )
            .asStretchyHeader(startingHeight: height) // Asosiy sehr shu yerda!
    }
}

E'tibor bering: Rasm ustiga oq tekst yozsangiz, agar rasm ham oqish bo'lsa tekstni umuman o'qib bo'lmay qoladi. Shuning uchun tekstning orqasiga (background) yengil LinearGradient (shaffofdan qoraga qarab) berib yubordik. Bu dizaynni juda professional ko'rsatadi.

Koddagi .asStretchyHeader() modifikatori SwiftfulUI paketi orqali avtomatik ishlaydi va ScrollView bilan birga rasmning cho'zilishini ta'minlaydi.

2. Pleylist tavsifi (Description Cell)

Rasmning darhol pastida Spotify pleylistlariga xos bo'lgan "Made for User" degan yozuv va juda ko'p mayda tugmalar (Share, Download, Shuffle, Play) keladi. Bu qism uchun alohida PlaylistDescriptionCell yaratamiz.

Bunda tugmalarni hammasini HStack ichida yonma-yon qilib joylaymiz, va Play tugmasini kattaroq hamda yashil qilib olamiz:

import SwiftUI

struct PlaylistDescriptionCell: View {
    var descriptionText: String = "Some description goes here"
    var userName: String = "Nick"
    var subheadline: String = "Some headline goes here"

    // Barcha tugmalarning action'larini ochiq qoldiramiz
    var onAddToPlaylistPressed: (() -> Void)? = nil
    var onDownloadPressed: (() -> Void)? = nil
    var onSharePressed: (() -> Void)? = nil
    var onEllipsisPressed: (() -> Void)? = nil
    var onShufflePressed: (() -> Void)? = nil
    var onPlayPressed: (() -> Void)? = nil

    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            Text(descriptionText)
                .foregroundColor(.spotifyLightGray)
                .frame(maxWidth: .infinity, alignment: .leading)

            // "Made for User" qismi
            HStack(spacing: 8) {
                Image(systemName: "applelogo")
                    .foregroundColor(.spotifyGreen)
                    .font(.title3)

                Text("Made for ")
                    +
                Text(userName)
                    .bold()
                    .foregroundColor(.spotifyWhite)
            }
            .font(.callout)
            .fontWeight(.medium)

            Text(subheadline)
                .foregroundColor(.spotifyLightGray)

            buttonsRow
        }
    }

    // Tugmalar qatori
    private var buttonsRow: some View {
        HStack(spacing: 0) {
            HStack(spacing: 0) {
                Image(systemName: "plus.circle")
                    .font(.title2)
                    .padding(8)
                    .background(Color.black.opacity(0.001))
                    .onTapGesture { onAddToPlaylistPressed?() }

                // qolgan tugmalar ham shunday...
            }
            .frame(maxWidth: .infinity, alignment: .leading)

            HStack(spacing: 8) {
                Image(systemName: "shuffle")
                    .font(.system(size: 24))
                    .onTapGesture { onShufflePressed?() }

                Image(systemName: "play.circle.fill")
                    .font(.system(size: 46))
                    .onTapGesture { onPlayPressed?() }
            }
            .foregroundColor(.spotifyGreen)
        }
    }
}

Bu darsimizda katta ma'lumotlarni qanday qilib qismlarga (Cells) ajratishni o'rgandik. Keyingi darsda ushbu Pleylist oynasini haqiqiy musiqalar qatori bilan to'ldiramiz va Sarlavha animatsiyasini tugatamiz.

Buy mea coffee