- Published on
SwiftUI crypto app — ma'lumotlarni grid formatida va statistika sifatida ko'rsatish
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
SwiftUI crypto app — ma'lumotlarni grid formatida va statistika sifatida ko'rsatish
Oldingi darsda DetailViewModel va CoinDetailDataService yordamida ma'lumotlarni yuklab oldik. Bu darsda ularni ekranda ko'rsatamiz. LazyVGrid — ikkita ustunli grid — statistikalarni chiroyli va samarali ko'rsatadi.
1. DetailView asosiy tuzilmasi
import SwiftUI
struct DetailView: View {
@StateObject private var vm: DetailViewModel
private let columns: [GridItem] = [
GridItem(.flexible()),
GridItem(.flexible())
]
private let spacing: CGFloat = 30
init(coin: CoinModel) {
_vm = StateObject(wrappedValue: DetailViewModel(coin: coin))
}
var body: some View {
ScrollView {
VStack {
// Yuqori bo'lim (grafik — keyingi darsda qo'shiladi)
Text("")
.frame(height: 150)
VStack(spacing: 20) {
overviewTitle
Divider()
descriptionSection // Tavsif matni
overviewGrid
additionalTitle
Divider()
additionalGrid
websiteSection // Havolalar
}
.padding()
}
}
.navigationTitle(vm.coin.name)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
navigationBarTrailingItems
}
}
}
}
2. Overview va qo'shimcha statistika gridi
extension DetailView {
private var overviewTitle: some View {
Text("Ko'rinish")
.font(.title)
.bold()
.foregroundColor(Color.theme.accent)
.frame(maxWidth: .infinity, alignment: .leading)
}
private var additionalTitle: some View {
Text("Qo'shimcha ma'lumotlar")
.font(.title)
.bold()
.foregroundColor(Color.theme.accent)
.frame(maxWidth: .infinity, alignment: .leading)
}
// Overview statistikasi: narx, bozor kap, reyting, hajm
private var overviewGrid: some View {
LazyVGrid(
columns: columns,
alignment: .leading,
spacing: spacing,
pinnedViews: []
) {
ForEach(vm.overviewStatistics) { stat in
StatisticView(stat: stat)
}
}
}
// Qo'shimcha statistika: yuqori/past narx, bloklash vaqti va hokazo
private var additionalGrid: some View {
LazyVGrid(
columns: columns,
alignment: .leading,
spacing: spacing,
pinnedViews: []
) {
ForEach(vm.additionalStatistics) { stat in
StatisticView(stat: stat)
}
}
}
}
LazyVGrid nima? Ikki parametr asosiy:
columnsvaspacing.GridItem(.flexible())— ikkita ustun teng kenglikda bo'linadi.LazyVGridekranda ko'rinadigan elementlarnigina yaratadi — bu katta ro'yxatlarda samarali.
3. Tanga tavsifi (description) bo'limi
CoinGecko API-dan kelgan tavsif matnini ko'rsatamiz. U uzun bo'lgani uchun — "ko'proq ko'rsatish" tugmasi qo'shamiz:
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)
.lineLimit(showFullDescription ? nil : 3) // nil = cheksiz qator
.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)
}
}
}
}
Nima uchun
lineLimit(nil)?lineLimit(3)— 3 qatorgacha,lineLimit(nil)— cheksiz. Tugmani bosganda ular almashinadi.
4. NavigationBar-dagi tanga belgisi va nomi
private var navigationBarTrailingItems: some View {
HStack {
Text(vm.coin.symbol.uppercased())
.font(.headline)
.foregroundColor(Color.theme.secondaryText)
CoinImageView(coin: vm.coin)
.frame(width: 25, height: 25)
}
}
5. Veb-sayt va Reddit havolalari
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-ning ichki brauzer yechimi. Bosilganda Safari ochilmaydi — balki ilovaning ichidaSFSafariViewControllerochiladi (yoki standart brauzerga o'tadi). Bu foydalanuvchi uchun qulay.
6. DetailViewModel-da coin saqlash
DetailViewModel-da coin xususiyatini @Published qilish kerak — NavigationBar-ga uzatish uchun:
class DetailViewModel: ObservableObject {
@Published var overviewStatistics: [StatisticModel] = []
@Published var additionalStatistics: [StatisticModel] = []
@Published var coinDescription: String? = nil
@Published var websiteURL: String? = nil
@Published var redditURL: String? = nil
let coin: CoinModel // NavigationBar uchun ochiq
// ...
}
7. Natija
Ilovada Bitcoin yoki boshqa tangani bosing:
- Ko'rinish bo'limi: joriy narx, bozor kap, reyting, hajm — ikkita ustunda
- Tavsif: qisqa ko'rinish, "ko'proq ko'rsatish" tugmasi
- Qo'shimcha: 24s maksimal/minimal narx, foiz o'zgarishi, bloklash vaqti, hashing algoritmi
- Havolalar: rasmiy veb-sayt va Reddit
Bitcoin
Joriy narx: $43,250.12 Bozor kap: $842.5Bn
Reyting: 1 24s hajm: $28.3Bn
Qo'shimcha ma'lumotlar
24s maksimal: $44,100.00 24s minimal: $42,800.00
Narx o'zgarishi: +$1,250 Bozor kap o'zg: +$15.2Bn
Blok vaqti: 10 Hashing: SHA-256
"Ma'lumotlar bir joyda chiroyli grid shaklida joylashgan. LazyVGrid-ning kuchli tomoni shunda — element sonini o'zgartirsak, view avtomatik yangilanadi. Qo'shimcha view kodi yozish shart emas!"
Keyingi darsda biz ilovaning yuqori qismiga narx grafigini qo'shamiz. 🚀