מבוא ל- Dynamic Collection Views in SwiftUI

יישומים מודרניים דורשים נוזל, ממשקי קבצים מתאימים להגיב בחסד לגודל נתונים שונים, נטיות המכשיר ומדפי מסך.ב UIKit, תצוגות איסוף מספקים מנגנון חזק אך פועלי לבניית פריסות דמויות רשת. SwiftUI מפשטות את זה באופן דרמטי עם ממשק ה-AP הברור שלה, במיוחד באמצעות MacLT:0LazyVGridFLT:1 ו-LT:2Gir:

A (FLT:0 דינמית איסוף תצוגת אוסף הפריסה FLT:1 להתאים את ספירת העמודה שלה, גובה שורות, ספיגה, או sizing התנהגות המבוססת על רוחב מיכל זמין, מספר הפריטים, או התוכן עצמו. מאמר זה ינחה אותך באמצעות בניית פריסות כאלה ב SwiftUI, מכסה את הכל מהגדרה רשת בסיסית להתנהגויות מתקדמות, כוונון, שילוב עם אנימציה עד הסוף, יש לך ביצועים גמישים, ליצור תצוגות, ליצור תצוגות עצמאיות, ליצור תצוגות.

המונחים: LazyVGrid and LazyHGrid

(הופנה מהדף "החלל" (FLT:0 LazyVGridFLT:1) ו-"FLT:2"LazyHGridFLT 3:0 (רשת גלילה של גילוח) 1 (מסמנים את ילדיהם, כלומר, תצוגות נוצרות רק כפי שהן נראות על המסך - תכונה חיונית לטיפול במערך נתונים גדול ללא זיכרון אנפילי, הן קוד אנפילי של נתונים מינוסים וקודים של מינוסים.

גרידם קונריגציה

(ב) כדי להגדיר מבנה רשת, אתה יוצר מערך של תפוצה:0 (Grid Itememememph:1) דוגמאות של כל אחד מהם מייצג עמודה אחת (ב-FLT:2) או שורה אחת (ב-FLT 3: 3 תכונות מפתח:

  • (ב) ויקרא י"ד: "וַיֹּאמַר עַמֶר נָא עַמֶר עַל עַמֶּה הוּא" (בראשית כ"ד, ט).
  • (ב) ⁇ (ב"ד): ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇
  • (ב) ⁇ :0) ,[דרוש מקור]: "[דרוש מקור]" (שם י"ד: ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇

בחירת מצב sizing מגדיר את גמישות הפריסה הכוללת:

  • (ב) (ב):0 (FixedFLT:1) - רוחב Explicit (או גובה) לכל עמודה / מעלה.שימושי כאשר אתה צריך בדיוק sizing, למשל, פריסה תלת-קולרית של תאים קבועים 100 נקודות.
  • (FLT:0)FlexibleFLT:1 - כל פריט רשת יכול למתוח כדי למלא את החלל הזמין, עם גבולות מינימליים ומרביים אופציונליים.זהו הבחירה הנפוצה ביותר עבור עמודות דינמיות, אפילו בחלל.
  • (FLT:0) AdaptiveFLT:1) - הרשת קובעת באופן אוטומטי כמה פריטים מתאימים לשורה בעמודה המבוססת על גודל מינימלי מוגדר.זוהי הדרך הפשוטה ביותר לבצע פריסה דינמית שמגיבת לרוחב המסך.

לדוגמה, כדי ליצור רשת שמתאימה באופן אוטומטי לטורות רבות ככל האפשר, כל אחד עם רוחב מינימלי של 100 נקודות, אתה כותב:

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

קו יחיד זה מניב פריסה שמתאימה בעמודה אחת על אייפון צר למספר עמודות על iPad בנוף - בדיוק ההתנהגות שאנו רוצים עבור פריסות דינמיות.

בניית רשת דינמית בסיסית

נתחיל עם רשת פשוטה ודינמית מלאה באמצעות FLT:8 sizing. להלן הוא תצוגה מלאה המציגה מגוון של מחרוזת ברשת תגובה:

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()
 }
 }
}

כאן, כל פריט נדרש לפחות 80 נקודות רחבות וגבוהות. הפריט רשת (FLT:10), ולאחר מכן מחשב באופן אוטומטי כמה פריטים יכולים להתאים לשורה לאור רוחב זמין, מכבד את רוחב המינימום.התוצאה היא פריסה שזרימה באופן חלק כאשר המכשיר מסתובב או החלון הוא בגודל מחדש (על iPad או Mac).

גישה זו עובדת היטב עבור תוכן פשוט, אך עבור שליטה רבה יותר אתה צריך לשלב את 11 עם פריטים (FLT:12), או להשתמש ב-FLT:13 כדי לחשב את סעיפים טור מותאם אישית.

שימוש ב-Gמטריה Reader for Precise Dynamic lines

בעוד ש-FLT:14 מטפל במקרים רבים, לפעמים אתה רוצה להגדיר מספר מדויק של עמודות על בסיס רוחב מכולה - לדוגמה, תמיד 2 עמודות על אייפון בדיוקנאות, 3 בנוף, ו-4 על iPad.ה-FLT:0Geometry ReaderphigerFLT:1 מציג את הגודל הנוכחי של ההורה שלו, המאפשר לך לחשב את העמודה האופטימלית דינמי.

דוגמה: מצגת טור הסתגלות

הנוף הבא קורא את רוחב זמין ומצמיד ספירת עמודה המבוססת על רוחב פריט מטרה:

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()
 }
 }
 }
}

(בפועל, על האדם לשמור על ערך ה-FLT:0) בתוך משתנה או להשתמש בו באותה הסגרה הדוגמא לעיל משתמשת במשתנה עוזר בתוך הסגר לבהירות.תמיד להבטיח שלא תעטוף את הגוף כולו ב-FLT:17 ללא צורך - זה יכול לשבור את הפריסה אם נעשה שימוש בתצוגה העליונה.

טכניקה זו מעניקה לך שליטה מלאה על מספר העמודות תוך שמירה על פריטים גמישים כך שהם ממלאים את רוחב אפילו.You יכול גם להוסיף מגבלות מינימליות ומרביות לפריטים גמישים כדי להימנע מתאים מתוחים או מלוטשים מאוד.

התאמת Row Level דינמי

פריסות דינמיות אינן רק על עמודות - גבהים שורות יכולים גם להשתנות בהתבסס על תוכן. SwiftUI לא מספק רשת "הפצה אוטומטית" ישירה כמו UIKit'sFLT 18 עם גדלים מוערכים.

לדוגמה, אתה יכול לעשות כל תא בגודל עצמי על ידי פיזור גבהים מפורשים ומאפשר תוכן פנימי לקבוע את הגודל. SwiftUI באופן אוטומטי לחשב את גובה התא מבוסס על הפריט הגבוה ביותר בכל שורה (עבור רשתות אנכיות) אבל אם אתה צריך באמת גבהים שורת משתנה (כמו פריסת masonry), אתה צריך גישה אישית - לעתים קרובות באמצעות LT:20 עם מדריכים מותאם אישית או עוטפת רשת של 2 מעלות צלזיוס, אבל זה דורש גבהים מתקדמים יותר מאשר את כל אחד מהם).

עקבו אחרי Lazy Loading

אחד היתרונות העיקריים של (FLT:24 ו-FLT:25) הוא התנהגות הטעינה עצלנית שלהם.הם רק ליצור נופים עבור הפריטים כי הם גלויים כיום (בנוסף למצמץ קטן) זה הופך אותם יעילים עבור נתונים עם מאות או אפילו אלפי פריטים.

  • (ב) [17] , ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇
  • (FLT:0) ללא חישובים יקרים בתוך הגוף של ההרחבה: שמור על תצוגות תאים פשוטות.
  • (ב) (ב[[1924]], [[1924]]]], [[1924]]]]]], [[1924]]]]]], [[1924]]]], [[1924]]]]]]]], [[1924]]]]]], [[1924]]]]]], [[1924]]]]]]]], [[1924]]]]]]
  • (ב) ב[[1924]], [[1924]]]], [[1924]]]]]], [[1924]]]]]], [[1924]]]]]], [[1924]]]]]]]], [[1924]]]]]], [[1924]]]]]], [[1924]]]]]]]], [[1924]]]]]]]]

שילוב של דינמיות לייפנים עם Animations

האנימציה ב SwiftUI יכולה לגרום לשינויים בתחושה טבעית ומלוטשת.לדוגמה, כאשר מספר העמודות משתנה (בשל סיבוב או חלון גודל), ניתן לחבר את פריטי הרשת לעמדות החדשות שלהם.הדרך הקלה ביותר היא לעטוף את הרשת במודולטור (FLT:36) או להשתמש במכוון FLT:37 עם ערך שגורם לשינוי.

שינוי עמוד

הנה הרחבה של הדוגמה הדינמית הקודמת עם מעבר אנימציה:

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)
 }
 }
 }
}

על ידי נטישת ערך האנימציה ל-FLT:39 SwiftUI יכיר את ההכנסה, הסרה וההפצה מחדש של פריטים כאשר מספר העמודות משתנה.You יכול גם להשתמש ב-FLT:40 להחלפה מתקדמת יותר בין הפריסה.

דוגמאות מעשיות: Real-World Dynamic Layouts

בואו נלך דרך שני תרחישים נפוצים כי ליהנות מעיצובים דינמיים של תצוגות איסוף.

צילום: Grid

גלריית תמונות טיפוסית משתמשת ברשת תאים מרובעת שמתאימה לרוחב המסך.You רוצה שהתאים יהיו גדולים ככל האפשר תוך שמירה על מספר קבוע של עמודות (למשל, 2 על iPhone, 3 ב- iPhone Plus, 4 על iPad).

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)
 }
 }
}

לוח דינאמי עם גודל תאים משתנה

עבור לוח מחוונים, ייתכן שיש לך תאים של רוחב שונה - למשל, גרף גדול לוקח שני עמודות, סטטינים קטנים יותר לוקח עמודה אחת כל אחד.You יכול להשיג זאת על ידי שילוב של פריטים עם מכפילים מפורשים באמצעות מערך מותאם אישית FLT:44.

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
]

לאחר מכן, ברשת של ההרחבה , ניתן למפות סוגים שונים של נתונים לטבלאות עמודה שונות על ידי עוטפים פריטים במיכל אשר מרחיב כדי למלא את רוחב הרשת.זה דורש תיאום זהיר כי FLT:47 לא תומך באופן מקורי במגוון רחב של עיגולים. a Common Workroundup הוא להשתמש ב-FLT:48 Modifier (זמין ב- iOS 16+) או אינדקס באופן ידני על ידי התפלגות נתונים מלאים.

עבור iOS 16 ואילך, אתה יכול להשתמש במאמת ⁇ על נוף בתוך הרשת כדי לציין כמה עמודות יש ל אורך:

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

זוהי הדרך הנקיה ביותר ליצור פריסת לוח נתונים דינמי אמיתי עם גדלים תאים מעורבים.

תוצאות עבור Large Data Sets

כאשר מתמודדים עם אלפי פריטים, אפילו טעינה עצלנית יכולה להוביל לבלוטות אם כל תא מורכב.כאן טכניקות מתקדמות כדי לשמור על רשתות דינמיות חלק:

  • (ב) ויקרא י"א) ויקרא (ב"ד) ב[[1924]], [[1924]], [[1924]]]]]], [[1924]]]], [[1924]]]]]], [[1924]]]]]]
  • (ב) [ה] [ה]] [ה]] [ה]] [ה]] [ה]]] ל[ה] [ה]][ה]]] ל[ה] [ה]] ל[ה]] [ה], ל[ה], ל[ה[[המאה ה-[[המאה ה-20]], ו[[המאה ה-20]], ו[[1948]],]], ו[[המאה ה[[המאה ה-20]],]],]],]],]], [[המאה ה[[1948]],]],]],]], [[המאה ה[[1924]],]], [[1924]], [[המאה ה[[1924]],]], [[1924]],]],]],]], [[1924]], [[1924]], [[ה[[1924]],]],]], [[1924]], [[1924]], [[ה[[1924]], [[1924]], [[1924]], [[1924]], [[1924]], [[1924]], [[1924]], [[1924]], [[1924]], [[1924]], [[1924]], [[19
  • (FLT:0) לימיט recomputation of הפריסה FIRLT:1) - להימנע מקביעת לוגיקה של הפריסה דינמי בתוך הגוף של התא.
  • (ב) [ה]: [ה] [ה] [ה]] [ה]] [ה] [ה], אם תשנה לחלוטין את מבנה הרשת (למשל, מעבר בין 2 עמודים ל- 3), הקצאת חדש (FLT) לרשת שאילץ אותו לנסח מחדש לחלוטין, אשר יכול להיות מהיר יותר מאשר לנסות לשנות שינוי מורכב.

משאבים חיצוניים כדי לחזק את הידע שלך

כדי לחקור עוד תצוגות איסוף דינמיות ב SwiftUI, מתייחס משאבים רשמיים וקהילתיים אלה:

  1. (הופנה מהדף יחזקאל לזיוואגרי, ההרחבה הראשונה של אפל) ,התייחסות הרשמית לכל הפרמטרים וההתנהגויות.FLT:2 Apple Developer Documentation: LazyVGridFLT 3
  2. (ב) [ה]המדריך ל-GirdItemememveFLT: [ה]: [ה] [ה], [ה], [ה], הוא כולל את כל שלוש האסטרטגיות המרשימות עם דוגמאות אינטראקטיביות.
  3. (ב) [15] ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇
  4. (ב) [15] ,5 ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇

Best Practices summary

יצירת פריסת תצוגה דינמית של אוסף ב SwiftUI דורשת איזון גמישות עם ביצועים.כאן רשימה מהירה עבור רשתות מוכנות ייצור:

  • החל מ-[[1960]], ב[[1948]], [[1961]], [[1924]], [[1924]], [[1924]]]], [[1924]], [[1924]]]]]], [[1924]]]]]], [[1924]]]]]]
  • תמיד יש ערך ייחודי (בשיתוף:62) או תואמים ל-FLT:63
  • השתמש ב-FLT:64 עם ערך שמשנה (כמו ספירת העמודה) להחלפה חלקה.
  • עבור גדלים תאים מעורבים, מעדיפים את ה-FLT:65 על iOS 16+ או לעצב פריסת חתירה אישית.
  • פרופיל הרשת שלך עם מכשירים כדי לאמת טעינה עצלנית עובד ותאים אינם מסירים תוכן מסך.
  • מבחן על גודלי מכשירים מרובים ונטיות - פריסות דינמיות שנראים נהדרות על מסך אחד עלול לפרוץ על המסך אחר.

תצוגות איסוף דינמיות מעצימות אותך לבנות יישומים שמרגישים ילידים וגיבים בכל מכשיר אפל.עם הכלים המפוכחים של SwiftUI, תוכל להשיג מה שנדרש פעם עשרות שורות של קוד UIKit בתוך קומץ של מרכיבים אקספרסיביים, ניתנים לחזרה.