Published on

SwiftUI crypto app — kengaytirilishi mumkin bo'lgan tavsif va havolalar bo'limi

Authors

SwiftUI crypto app — kengaytirilishi mumkin bo'lgan tavsif va havolalar bo'limi

Bu darsda biz DetailView-ni yakunlaymiz. Har bir tanga uchun tavsif matnini qo'shamiz — uni qisqa ko'rinishda (3 qator) yoki to'liq ko'rsatish imkonini beramiz. Shuningdek, rasmiy veb-sayt va Reddit havolalarini qo'shamiz.


1. CoinDetailModel-da readableDescription

CoinGecko tavsiflarida HTML teglari keladi (<p>, <a href...> va hokazo). Ularni olib tashlash uchun String+Extensions.swift-ga:

extension String {
    var removingHTMLOccurrences: String {
        // Regex: < dan > gacha bo'lgan har qanday HTML tegni o'chiradi
        return self.replacingOccurrences(
            of: "<[^>]+>",
            with: "",
            options: .regularExpression,
            range: nil
        )
    }
}

CoinDetailModel-da:

struct CoinDetailModel: Codable {
    // ...

    // HTML tegsiz tavsif (computed property)
    var readableDescription: String? {
        return description?.en?.removingHTMLOccurrences
    }
}

2. DetailViewModel-da yangi @Published o'zgaruvchilar

class DetailViewModel: ObservableObject {
    @Published var overviewStatistics: [StatisticModel] = []
    @Published var additionalStatistics: [StatisticModel] = []
    @Published var coinDescription: String? = nil   // yangi
    @Published var websiteURL: String? = nil        // yangi
    @Published var redditURL: String? = nil         // yangi

    // ...

    private func addSubscribers() {
        // Statistika subscriberi (oldindan bor)...

        // Tavsif va havolalar uchun alohida subscriber
        coinDetailService.$coinDetails
            .sink { [weak self] returnedCoinDetails in
                self?.coinDescription = returnedCoinDetails?.readableDescription
                self?.websiteURL = returnedCoinDetails?.links?.homepage?.first
                self?.redditURL = returnedCoinDetails?.links?.subredditURL
            }
            .store(in: &cancellables)
    }
}

3. descriptionSection — kengaytiriladigan tavsif

extension DetailView {

    @State private var showFullDescription: Bool = false

    private var descriptionSection: some View {
        ZStack {
            if let coinDescription = vm.coinDescription,
               !coinDescription.isEmpty {
                VStack(alignment: .leading) {
                    Text(coinDescription)
                        // Tugma holati: nil = cheksiz, 3 = qisqa
                        .lineLimit(showFullDescription ? nil : 3)
                        .font(.callout)
                        .foregroundColor(Color.theme.secondaryText)

                    Button {
                        withAnimation(.easeInOut) {
                            showFullDescription.toggle()
                        }
                    } label: {
                        Text(showFullDescription ? "kamroq ko'rsatish ▲" : "ko'proq ko'rsatish ▼")
                            .font(.caption)
                            .bold()
                            .padding(.vertical, 4)
                    }
                    .accentColor(.blue)
                }
                .frame(maxWidth: .infinity, alignment: .leading)
            }
        }
    }
}

lineLimit(nil) va lineLimit(3) animatsiyasi: SwiftUI bu o'zgarishni silliqlik bilan animatsiya qiladi. Foydalanuvchi tugmani bosganda matn pastga yozilib boradi yoki yuqoriga yig'iladi — juda chiroyli effekt.


4. websiteSection — havolalar

private var websiteSection: some View {
    VStack(alignment: .leading, spacing: 20) {
        if let websiteString = vm.websiteURL,
           let url = URL(string: websiteString) {
            Link("Rasmiy veb-sayt 🌐", destination: url)
        }

        if let redditString = vm.redditURL,
           let url = URL(string: redditString) {
            Link("Reddit 🔗", destination: url)
        }
    }
    .accentColor(.blue)
    .frame(maxWidth: .infinity, alignment: .leading)
    .font(.headline)
}

Link SwiftUI komponenti: iOS 14+ da mavjud. Bosilganda ilovaning ichida Safari ochiladi (SFSafariViewController), tashqariga chiqmaydi. Foydalanuvchiga qulay.


5. DetailView body-ga qo'shish

VStack(spacing: 20) {
    overviewTitle
    Divider()
    descriptionSection    // ← yangi
    overviewGrid
    additionalTitle
    Divider()
    additionalGrid
    websiteSection        // ← yangi
}
.padding()

6. Natija

Bitcoin detail ekraniga o'tsangiz:

  • Tavsif: Dastlab 3 qator ko'rinadi, "ko'proq ko'rsatish ▼" tugmasi bor
  • Bosilganda: Tavsif to'liq yozilib chiqadi, tugma "kamroq ko'rsatish ▲" ga o'zgaradi
  • Havolalar: "Rasmiy veb-sayt 🌐" va "Reddit 🔗" havolalari pastda joylashgan

Polkadot yoki Uniswap kabi tanglarga o'tib ko'ring — har birida tavsif va havolalar farqli keladi.

"Bu oddiy view ko'rinishi lekin foydalanuvchi uchun juda muhim. Kimdir Bitcoin ustiga bossaydi va u haqida o'qiy oladi. Mana shu ma'no yashash momenti — faqat narxlar emas, ma'lumot ham bor!"

Keyingi darsda sozlamalar ekranini (SettingsView) yaratamiz. 🚀

Buy mea coffee