Swiftui'de Dinamik Bir Koleksiyon Nasıl Oluşturulur

SwiftUI'deki Dinamik Koleksiyona Giriş

Modern iOS uygulamaları, agresif API ile cevap veren akışkanlar, özellikle de ekran boyutları, cihaz yönlendirmeleri ve ekran boyutları. UIKit, koleksiyon görüşleri, ağ benzeri yapılar oluşturmak için güçlü ama fiilose mekanizması sağlar. SwiftUI bunu en az kodla basitleştirir, özellikle de üretime hazır UIs oluşturmak için daha kolay hale getirir.

AAHRAT:0)dinamik koleksiyon bakış düzeni[[Dönetici:0)) Bu makale, sütun sayılarını, sıralarını, yüksekliğini, genişleyen veya mevcut konteyner genişliğine dayanan boyutlandırma davranışını, esnek, ilgi çekici ve içerikli koleksiyonuz için size rehberlik edecektir.Bu makale, SwiftUI'deki her şeyi temel ağdan gelişmiş bir adaptasyon davranışı, performans ve animasyonlarla entegrasyon için temel bir temele sahip olacaktır.

Core components: LazyVGrid ve LazyHGrid

SwiftUI iki birincil ağ konteyneri sağlar: [[Dönetici:0)LazyVGrid[Döneticisel kaydırma ızgarası) ve [[Dönetici:2)LazyHGrid) (horizontal kaydırma ızgarası) , her iki kaynaktan da görünür hale gelir.

GridItem Konsrük

Bir ızgaranın yapısını tanımlamak için, bir dizi İLDİT:0)GridItem) örneklerini temsil eder.Her bir sütunu (inENFLT:2) veya tek bir satır (inurFLT:3).

Büyüklük modu seçimi genel düzeni esnekliğini tanımlar:

Örneğin, mümkün olduğunca çok sütuna sahip bir ızgara oluşturmak için, her biri 100 puanın minimum genişliği ile, yazabilirsiniz:

let columns = [
 GridItem(.adaptive(minimum: 100))
]

Bu tek çizgi, bir sütundan diğerine dar bir iPhone'da bir iPad'de birkaç sütuna adapte olan bir düzen verir - tam olarak dinamik yapılar için istediğimiz davranış.

Temel bir Dinamik Grid inşa

Basit, tamamen dinamik bir ağ ile başlayalım DÖRT:8. Boyutlu. Aşağıda, bir dizi dizeleri yanıtlayan bir ızgarada gösteren tam bir görünüm vardır:

struct AdaptiveGridView: View {
 let items = Array(1...20).map { "Item \($0)" }

 var body: some View {
 ScrollView {
 LazyVGrid(
 columns: [GridItem(.adaptive(minimum: 80), spacing: 12)],
 spacing: 12
 ) {
 ForEach(items, id: \.self) { item in
 Text(item)
 .frame(minWidth: 80, maxWidth: .infinity, minHeight: 80)
 .background(Color.blue.opacity(0.2))
 .cornerRadius(8)
 }
 }
 .padding()
 }
 }
}

İşte her öğe en az 80 puan geniş ve uzun bir şekilde zorlanılır.ŞUYUÇMA:) Kafe eşyası daha sonra otomatik olarak mevcut genişlikte kaç öğenin sıraya sığabileceğini hesaplar, minimum genişlike saygı gösterin. Sonuç, cihazın geri döndüğünüzde veya pencerenin yeniden boyutlandırıldığı bir düzendir (on iPad veya Mac).

Bu yaklaşım basit içerik için iyi çalışır, ancak daha fazla kontrol için genellikle [[Ahlaklar ile ►FLT:12) öğeleri birleştirmek veya özel sütun sayılarını hesaplamak için [[ŞUFONTT:13) gerekir.

GeometryReader for Precise Dynamic Column Counts

[[Dind: 14) Birçok vakayı ele alırken, bazen, kontrasep genişliğine dayanan tam sayıda sütun ayarlamanızı istersiniz - örneğin, portrede bir iPhone'da her zaman 3 sütun ve iPad'de 4.TheurDometryReader

Örnek: An Adaptive Column Count

Aşağıdaki görüş, mevcut genişlik ve bir sütun sayısını hedef bir öğe genişliğine dayanan olarak okur:

struct DynamicColumnGridView: View {
 let items = Array(1...30).map { "Item \($0)" }
 let targetItemWidth: CGFloat = 120

 var columns: [GridItem] {
 let count = max(Int(geometryProxy.size.width / targetItemWidth), 1)
 return Array(repeating: GridItem(.flexible(), spacing: 12), count: count)
 }

 var body: some View {
 GeometryReader { geometry in
 ScrollView {
 let width = geometry.size.width
 let count = max(Int(width / targetItemWidth), 1)
 let columns = Array(repeating: GridItem(.flexible(), spacing: 12), count: count)

 LazyVGrid(columns: columns, spacing: 12) {
 ForEach(items, id: \.self) { item in
 Text(item)
 .frame(minWidth: 0, maxWidth: .infinity, minHeight: 80)
 .background(Color.green.opacity(0.3))
 .cornerRadius(8)
 }
 }
 .padding()
 }
 }
 }
}

[FONT:0)İmportant:[Dönetici:[Dönetici:0) Uygulamada tüm vücudu kapatmanıza izin vermek gerekir; değişken içinde değer depolanmalıdır veya aynı kapatma içinde kullanabilirsiniz. Yukarıdaki örnek, açıklık için bir yardımcı değişken kullanır.

Bu teknik size esnek eşyaları tutarken sütunların sayısını tam olarak kontrol eder, böylece genişliği doldurabilirsiniz. Ayrıca son derece uzatılmış veya squashed hücrelerden kaçınmak için minimum ve maksimum kısıtlamalar da ekleyebilirsiniz.

Row Heights Dinamik Olarak Adapting

Dinamik düzenler sadece sütunlar hakkında değil - sıra yükseklikler de içeriğe göre değişebilir. SwiftUI, UIKit'sFLT:18 gibi doğrudan “otomatik” bir ızgara sunmuyor. Ancak, tahmin edilen boyutlarla benzer sonuçlar elde edebilirsiniz.

Örneğin, her bir ızgara hücre kendini açıkça ortaya çıkarmak ve içsel içeriği boyut belirlemenize izin verebilirsiniz. SwiftUI, her satırdaki en yüksek öğeye dayanan hücre yüksekliğini otomatik olarak hesaplayacaktır (daha gelişmiş ve bunun dışında değişken satırlara ihtiyacınız varsa), özel bir yaklaşıma ihtiyacınız vardır - genellikle standart kılavuzları kullanarak veya yüksek çözünürlükte bir satırda bulunan bir satırda yüksek çözünürlükte (örneğin, sütunda farklı yükseklikler ile birlikte)

Lale ile Büyük Veri Setleri Yüklemek

Şu anda görünür olan öğeler için sadece birkaç veya binlerce ürün için verimli hale getiriyorlar. Ancak, düzgün performansları korumak için birkaç en iyi uygulama var: Sadece şu anda görünür olan öğeler için görüş yaratıyorlar (artı küçük bir tampon).

Animasyonlarla Dinamik Layoutları birleştirmek

SwiftUI'deki animasyonlar, yeni pozisyonlara ızgarayı kapatabilir veya değiştirirken, sütunların sayısını değiştirir (dönüşüm veya pencere yeniden boyutlandırmaya çalışır), şebekeleri yeni pozisyonlara animatelayabilirsiniz.

Bölünme Köşesi Değişiklikleri

İşte animasyonlu geçişle önceki dinamik sütun örneğinin bir uzantısı:

struct AnimatedDynamicGridView: View {
 let items = Array(1...20).map { "Item \($0)" }
 @State private var targetItemWidth: CGFloat = 120

 var body: some View {
 GeometryReader { geometry in
 ScrollView {
 let width = geometry.size.width
 let count = max(Int(width / targetItemWidth), 1)
 let columns = Array(repeating: GridItem(.flexible(), spacing: 12), count: count)

 LazyVGrid(columns: columns, spacing: 12) {
 ForEach(items, id: \.self) { item in
 Text(item)
 .frame(minWidth: 0, maxWidth: .infinity, minHeight: 80)
 .background(Color.orange.opacity(0.4))
 .cornerRadius(8)
 .transition(.scale.combined(with: .opacity))
 }
 }
 .padding()
 .animation(.spring(response: 0.4, dampingFraction: 0.7), value: count)
 }
 }
 }
}

Animasyonu [[Dint| ⁇ | ⁇ | ⁇ | ⁇ | ⁇ | ⁇ | ⁇ t ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇

Pratik örnekler: Gerçek Dünya Dinamik Layouts

Dinamik koleksiyon görünüm düzeninden yararlanan iki ortak senaryodan geçelim.

Foto Galeri Grid

Tipik bir fotoğraf galerisi ekran genişliğine adapte olan bir kare hücre ağı kullanır. Hücrelerin sabit sütunlar tutarken mümkün olmasını istiyorsunuz (örneğin, iPhone Plus'ta 2, iPad'de 3, iPhone Plus'ta 4, iPad'de 4.) usingFLT:41, boyut sınıflarına dayanan bir koşullu sütun sayısı basit:

struct PhotoGalleryGrid: View {
 let images: [String]

 @Environment(\.horizontalSizeClass) var sizeClass

 var columns: [GridItem] {
 let count = sizeClass == .compact ? 2 : 4
 return Array(repeating: GridItem(.flexible(), spacing: 2), count: count)
 }

 var body: some View {
 ScrollView {
 LazyVGrid(columns: columns, spacing: 2) {
 ForEach(images, id: \.self) { imageName in
 Image(imageName)
 .resizable()
 .aspectRatio(1, contentMode: .fill)
 .clipped()
 }
 }
 .padding(.horizontal, 2)
 }
 }
}

Varied Hücre Boyutları ile Dinamik Dashboard

Bir pano için, farklı genişliklerin hücrelerine sahip olabilirsiniz - örneğin, her bir sütunu alan büyük bir grafik, her biri sütunu alan küçük istatistikler bunu, açık multipliers kullanarak elde edebilirsiniz. Örneğin:

let columns: [GridItem] = [
 GridItem(.flexible(minimum: 80), spacing: 12), // small stat cell
 GridItem(.flexible(minimum: 160), spacing: 12), // wide cell
 GridItem(.flexible(minimum: 80), spacing: 12) // small stat cell
]

Sonra, ızgaranın 15.Ücretsizce farklı veri türlerini farklı sütunlara haritalayabilirsiniz.Bu, verileri tam bir satır dolduran bölümlere bölmek için genişleyen bir konteynere.Bu, dikkatli bir koordinasyon gerektirir.Çünkü çok-column spans. ortak bir çalışma alanı kullanmak kolaydır.

iOS 16 ve daha sonra, aranjyondaki bir görüşe göre, bu görüşün ne kadar sütunların yayılacağını belirtmeniz gerekir:

LazyVGrid(columns: columns, spacing: 12) {
 ForEach(dashboardItems, id: \.id) { item in
 DashboardCell(item: item)
 .gridCellColumns(item.columnSpan)
 }
}

Bu, karışık hücre boyutları ile gerçek dinamik bir pano düzeni oluşturmak için en temiz yoldur.

Büyük Veri kümeleri için Performansı

Binlerce ürünle uğraşırken, tembel yükleme bile her hücre karmaşıksa gecikmelere yol açabilir. İşte dinamik ızgaralarınızı düzgün tutmak için gelişmiş teknikler:

Dış Kaynaklar Bilginizi Derinleştirmek

SwiftUI'de dinamik koleksiyon görüşlerini daha fazla araştırmak için, bu resmi ve topluluk kaynaklarına atıfta bulun:

  1. [FONT=0) Apple'ın LazyVGrid Dokümantasyon[Dönetici:0)[Dönetici ve davranışlar için resmi referans. [FONTT:2).
  2. [FONT=0)Quick Start Guide for GridItem[Dönetici][Dönetici:0)Quick Start Guide for GridItem[[Dönetici: 0,0)[Dönetici:0))
  3. [FONT=0]SwiftUI, Örnek olarak – Grid Layouts[[Dönetici:0) – Swift ile pratik bir ders, adaptif ve esnek ızgaralar içeren Swift ile pratik bir derstir.[/FLT:3).
  4. [FONT=0)SwiftUI Lab: Lazy Grids – Performans ve özelleştirmelere ayak bas.]

En İyi Uygulama Özetleri

SwiftUI'de dinamik bir koleksiyon görünümü düzeni oluşturmak, performansla esneklik gerektirir. İşte üretim hazırlı ızgaralar için hızlı bir kontrol listesi:

Mastering dynamic collection views, her Apple cihazında yerli ve duyarlı hissettiğiniz uygulamaları güçlendirmek için sizi güçlendiriyor. SwiftUI'nin declarative araçlarıyla, sadece bir avuç ifade edici, yeniden kullanılabilir bileşenlerde bir kez gerekli düzinelerce UIKit kodu elde edebilirsiniz.