Published on

SwiftUI crypto app — ro'yxat uchun tangalar satri dizayni

Authors

SwiftUI crypto app — ro'yxat uchun tangalar satri dizayni

Ushbu darsda biz CoinModel ma'lumotlarini ekranda chiroyli tarzda ko'rsatish uchun CoinRowView (tangalar satri interfeysi) komponentini loyihalashtiramiz.

Loyihamizda preview-larni osonroq sozlash uchun maxsus mock ma'lumotlar tizimini hamda raqamlarni (valyuta va foizlarni) formatlash uchun Double klassiga kengaytma (extension) yaratamiz.


1. PreviewProvider uchun mock ma'lumotlar yaratish

Ro'yxat yoki satr preview-sini ko'rish uchun bizga har safar tanga obyekti kerak bo'ladi. Har safar kod ichida qo'lda tanga ma'lumotlarini yozib o'tirmaslik uchun, extensions papkasida PreviewProvider.swift faylini yaratamiz va u yerda singleton mock ma'lumotlar klassini tuzamiz:

import SwiftUI

extension PreviewProvider {
    static var dev: DeveloperPreview {
        DeveloperPreview.instance
    }
}

class DeveloperPreview {
    static let instance = DeveloperPreview()
    private init() {}

    // Preview-lar uchun ishlatiladigan mock bitcoin obyekti
    let coin = CoinModel(
        id: "bitcoin",
        symbol: "btc",
        name: "Bitcoin",
        image: "https://assets.coingecko.com/coins/images/1/large/bitcoin.png",
        currentPrice: 54321.0,
        marketCap: 1018388902094,
        marketCapRank: 1,
        fullyDilutedValuation: 1018388902094,
        totalVolume: 329103901,
        high24H: 56000.0,
        low24H: 53000.0,
        priceChange24H: 1200.0,
        priceChangePercentage24H: 2.25,
        marketCapChange24H: 120930193,
        marketCapChangePercentage24H: 2.1,
        circulatingSupply: 18800000,
        totalSupply: 21000000,
        maxSupply: 21000000,
        ath: 64800.0,
        athChangePercentage: -16.2,
        athDate: "2021-04-14T00:00:00.000Z",
        atl: 65.53,
        atlChangePercentage: 82000.0,
        atlDate: "2013-07-05T00:00:00.000Z",
        lastUpdated: "2021-09-20T00:00:00.000Z",
        sparklineIn7D: SparklineIn7D(price: [54000, 54100, 54321]),
        priceChangePercentage24HInCurrency: 2.25,
        currentHoldings: 1.5
    )
}

2. Double klassini kengaytirish

API-dan keladigan narxlar va foizlarni foydalanuvchiga dollar belgisi va kerakli o'nlik xonalar bilan chiroyli ko'rsatish uchun Double klassiga extension yozamiz. extensions ichida Double.swift ochamiz:

import Foundation

extension Double {

    // Raqamni 2 xonali valyuta formatiga o'tkazish
    private var currencyFormatter2: NumberFormatter {
        let formatter = NumberFormatter()
        formatter.usesGroupingSeparator = true
        formatter.numberStyle = .currency
        formatter.minimumFractionDigits = 2
        formatter.maximumFractionDigits = 2
        return formatter
    }

    func asCurrencyWith2Decimals() -> String {
        let number = NSNumber(value: self)
        return currencyFormatter2.string(from: number) ?? "$0.00"
    }

    // Raqamni 2 dan 6 xonagacha bo'lgan valyuta formatiga o'tkazish (juda kichik tangalar narxi uchun)
    private var currencyFormatter6: NumberFormatter {
        let formatter = NumberFormatter()
        formatter.usesGroupingSeparator = true
        formatter.numberStyle = .currency
        formatter.minimumFractionDigits = 2
        formatter.maximumFractionDigits = 6
        return formatter
    }

    func asCurrencyWith6Decimals() -> String {
        let number = NSNumber(value: self)
        return currencyFormatter6.string(from: number) ?? "$0.00"
    }

    // Ikki xonali o'nlik ko'rinishga keltirish (String format orqali)
    func asNumberString() -> String {
        return String(format: "%.2f", self)
    }

    // Foiz belgisini qo'shib qaytarish
    func asPercentString() -> String {
        return asNumberString() + "%"
    }
}

3. CoinRowView interfeysini yaratish

Endi views papkasi ichida CoinRowView.swift faylini yaratamiz. Ushbu satrda tanga reytingi (rank), belgisi (symbol), portfeldagi miqdori (holdings) va narx o'zgarishi ko'rsatiladi. Kodni toza saqlash uchun satrning chap, o'rtacha va o'ng ustunlarini extension-larga ajratib chiqamiz:

import SwiftUI

struct CoinRowView: View {

    let coin: CoinModel
    let showHoldingsColumn: Bool

    var body: some View {
        HStack(spacing: 0) {
            leftColumn

            Spacer()

            if showHoldingsColumn {
                centerColumn
            }

            rightColumn
        }
        .font(.subheadline)
    }
}

struct CoinRowView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            CoinRowView(coin: dev.coin, showHoldingsColumn: true)
                .previewLayout(.sizeThatFits)

            CoinRowView(coin: dev.coin, showHoldingsColumn: true)
                .previewLayout(.sizeThatFits)
                .preferredColorScheme(.dark)
        }
    }
}

// CoinRowView ustunlari uchun extension kodi
extension CoinRowView {

    private var leftColumn: some View {
        HStack(spacing: 0) {
            Text("\(coin.rank)")
                .font(.caption)
                .foregroundColor(Color.theme.secondaryText)
                .frame(width: 30)

            // Hozircha tanga rasmi uchun joyga aylana (circle) qo'yamiz
            Circle()
                .frame(width: 30, height: 30)

            Text(coin.symbol.uppercased())
                .font(.headline)
                .padding(.leading, 6)
                .foregroundColor(Color.theme.accent)
        }
    }

    private var centerColumn: some View {
        VStack(alignment: .trailing) {
            Text(coin.currentHoldingsValue.asCurrencyWith2Decimals())
                .bold()
            Text((coin.currentHoldings ?? 0).asNumberString())
        }
        .foregroundColor(Color.theme.accent)
    }

    private var rightColumn: some View {
        VStack(alignment: .trailing) {
            Text(coin.currentPrice.asCurrencyWith6Decimals())
                .bold()
                .foregroundColor(Color.theme.accent)

            Text(coin.priceChangePercentage24H?.asPercentString() ?? "")
                .foregroundColor(
                    (coin.priceChangePercentage24H ?? 0) >= 0 ?
                    Color.theme.green : Color.theme.red
                )
        }
        // Har doim bir xilda turishi uchun o'ng ustunga ekran kengligiga nisbatan o'lcham beramiz
        .frame(width: UIScreen.main.bounds.width / 3.5, alignment: .trailing)
    }
}

Ushbu loyiha orqali biz tangalar satrini light va dark rejimlarga mos, shuningdek, narxning musbat yoki manfiyligiga qarab yashil/qizil rangda o'zgaradigan interfeysini yakunladik.

Keyingi darsda biz tarmoqdan (API) ma'lumotlarni yuklab olishni boshlaymiz! 🚀

Buy mea coffee