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).
- [FONT:0)Size [Dönetici: 3 boyutlu modlardan biri: [[Dahire, s.
- [FONT:0)Spacing[[DÜDÜT:1) – Aynı satırdaki eşyalar arasında yatay ağlaşma ( dikey ağlar için) veya dikey ağlama (kücret için)
- [FONT:0)Alignment[[Dönetici: 1))[Döneticiler bir ağ hücresinde nasıl uyum sağlarlar.
Büyüklük modu seçimi genel düzeni esnekliğini tanımlar:
- [FONT:0)Fixed[Dönetici:0) [Dönderlik genişliği (veya yüksekliğe) her sütun / yarı-kırıklığa ihtiyacınız olduğunda, e.g., üç noktalı hücre düzeni.
- [FONT:0]Flexible[[Dönemli: 1) – Her bir grid eşya mevcut alanı doldurmaya, minimum ve maksimum sınırlara sahip olabilir. Bu, dinamik, hatta uzay sütunları için en yaygın seçimdir.
- [FONT:0] Adaptif[[Dönetici:0)[[Dönetici:0))[[Dönetici:0)))))[Dönerli bir minimum boyuta dayanan sütun satırlarında kaç öğenin sığdığını otomatik olarak belirler.
Ö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).
- [FONT:0) stabil tanımlayıcılar [[Dönetici: 1 ) - Her zaman eşsiz bir şekilde parametre temin ederim.() için İLDİYORUMLAR için, SwiftUI verimli bir şekilde olabilir.
- [FONT:0) Vücuttaki pahalı hesaplamalar (Dönetici: 1) Hücre görüşlerini basit tutun. Karmaşık bir düzen hesaplamalarına ihtiyacınız varsa, onları ızgaranın dışında önceden yönlendir.
- [FONT:0]LeverageZEFLT:29] - Hücre görüşünüzü ►FLT:30'a uygun olarak veya [[ENFLT:31) modifier, SwiftUI, hücrenin verileri değiştirilince değişiklikler atabilir.
- [FONT:0)IZEFLT:32] [FONTD:0)[FONT:0)[FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT
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:
- [FONT=0)Öyle görüntü ve veriler[Dönetici:0)[Döneticileri ve verileri – UseAHFLT:51) veya asynchronously, cepte değil, hücrenin vücudunda.
- [FONT:0) Son derece büyük listeler için [[Dönetici:0)UseENFLT:53 ([FONT:0))) için, bir ağ düzeni için daha optimize edilmiş binlerce sıra için, [[FONTFLT: 7|15|3||p>||p>||p>|p>|p>|p>|p>|p>|p>|p>|p>|p>|p>|p>|p>|p>|p>|p>|p>|p>|p>|p>|p>|p>|p>|p>)
- [FONT:0]Limit yeniden düzenlenme[Dönetici: 1) Hücrenin vücudundaki dinamik düzeni mantığı koymaktan kaçının. Precompute geometrileri mümkün olduğunda.
- [FONT:0)UseENFLT:58] Tüm ağ üzerinde ) – Eğer ağ yapısını tamamen değiştirirseniz (örneğin, 2 sütundan 3)'a kadar geçiş yapın, ızgaraya yeni bir ata bindirmek tamamen yüklenerek, karmaşık bir değişiklik yapmaya çalışmaktan daha hızlı olabilir.
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:
- [FONT=0) Apple'ın LazyVGrid Dokümantasyon[Dönetici:0)[Dönetici ve davranışlar için resmi referans. [FONTT: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))
- [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).
- [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:
- En basit dinamik sütun sayı için başlangıç: <24|kullanıcı:60|kullanıcı kontrole ihtiyacınız olduğunda sadece kesin kontrole ihtiyacınız olduğunda.
- Her zaman eşsiz birFL:62 değerleri veya [[Bind:63) uygun.
- UseFLT:64, bu değişiklikler (parça sayı gibi) düzgün geçişlere değer.
- Karışık hücre boyutları için, tercih edin.ETHFLT:65 iOS 16+ veya özel bir sıra oluşturma.
- Karınızı tembel yüklemeyi doğrulamak için Instruments ile profilleyin çalışmak ve hücreler ekran dışı içerik değildir.
- Birden fazla cihaz boyutları ve yönelimleri test edin – bir ekranda harika görünen dinamik yapılar başka bir şekilde kırılabilir.
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.