برنامه نویسی 90 بازدید

در این مقاله اقدام به پیاده‌سازی یک لیست دینامیک با حالت خالی، خطا و در حال بارگذاری می‌کنیم. شاید با دیدن عنوان این نوشته از خود پرسیده باشید که منظور از لیست پیشرفته در SwiftUI چیست. در برخی موارد لازم است روی لیست‌های دینامیک زیادی کار کنیم که حالت‌های مختلفی از قبیل empty ،error ،items یا loading را نمایش می‌دهند. به این منظور عموما از فریمورک داده-محور IGListKit استفاده می‌کنیم تا این نوع از لیست‌ها را بتوانیم در پروژه‌های خود پیاده‌سازی کنیم. اما می‌توانیم با بهره گرفتن از SwiftUI و صرفاً با نوشتن چند خط کد این نوع از لیست‌ها را بسازیم. در بخش بعدی در مورد روش پیاده‌سازی این لیست‌ها با استفاده از SwiftUI توضیح خواهیم داد.

پیاده‌سازی

در این بخش به بررسی روش پیاده‌سازی و کامپوننت‌های مختلف مورد نیاز می‌پردازیم.

ListState

یک لیست پیشرفته (AdvancedList) باید بتواند حالت‌های متفاوت را نمایش دهد. حالت‌ها را می‌توانیم به سادگی با یک Enum تعریف کنیم. در کد زیر از اضافه کردن حالت خالی پرهیز کرده‌ایم.

ListService

این AdvancedList ما به یک کامپوننت نیاز دارد که ListState و items را ذخیره کرده و مدیریت کند. با کمک گرفتن از Combine و امکان data binding در SwiftUI تلاش می‌کنیم AdvancedList و ListService را به هم اتصال دهیم.

به این ترتیب حالت لیست را می‌توان تغییر داده و آیتم‌ها را از طریق ListService ویرایش کرده و AdvancedList را به طرز خودکار به‌روزرسانی کرد.

دو آیتم خاص در پیاده‌سازی ListService به نام‌های Item و AnyListItem وجود دارند.

Item

ما می‌خواهیم بتوانیم آیتم‌های مختلف را در لیست یکسانی نمایش دهیم. هر آیتم باید قابل شناسایی بوده و بتواند به صورت یک نمای SwiftUI قابل نمایش باشد. برای رسیدن به این مقصود Item را به Identifiable و پروتکل View مقید می‌کنیم.

func appendItems<Item: Identifiable>(_ items: [Item]) where Item: View {}

اما یک مشکل وجود دارد. ما نمی‌توانیم اشیای سازگار با Identifiable و با پروتکل View را در یک آرایه درون ListService ذخیره کنیم، زیرا پروتکل‌ها انواع مرتبط و قیدهای ژنریک دارند. به همین دلیل باید از type erasure استفاده کنیم.

یک نوع باکس به نام AnyListItem پیاده‌سازی کرده‌ایم که اطلاعات نوع مشخصه body را با استفاده از AnyView و اطلاعات نوع id را با استفاده از AnyHashable پاک می‌کند.

ListService و AnyListItem به صورت درونی اطلاعات نوع را از هر Item که به لیست اضافه می‌شود پاک می‌کنند.

AdvancedList

در نهایت به بررسی پیاده‌سازی نمای SwiftUI به نام AdvancedList می‌پردازیم. دستگیره‌های نما خودشان به حالت لیست جاری و آیتم‌های جاری وابسته هستند. به این منظور نمای AdvancedList به یک وهله از ListService نیاز دارید که حالت و آیتم‌های لیست را مدیریت می‌کند.

با بهره‌گیری از پوشش مشخصه ObjectBinding روی متغیر listService باید به نمای AdvancedList اعلام کنیم که به تغییرها وابسته باشد. به علاوه کاربر نمای AdvancedList باید بتواند یک نما برای حالت‌های empty ،loading و error لیست تعریف کند. ما از پوشش مشخصه ViewBuilder روی پارامترهای موجود در initializer برای نیل به این مقصود استفاده کردیم.

همچنان که پیشتر اشاره کردیم، به حالت خالی روی enum به نام ListState نیاز نداریم، زیرا می‌توانیم از isEmpty روی items استفاده کنیم. یک نکته خاص دیگر نیز در پیاده‌سازی ما وجود دارد. حالت error مربوط به ListState یک مقدار مرتبط با نوع Error دارد. به همین جهت خطا را به نمای error ارسال می‌کنیم که در صورت نیاز آن را نمایش دهد. بدین ترتیب پیاده‌سازی لیست پیشرفته به پایان می‌رسد. در بخش بعدی کاربرد AdvancedList را مورد بررسی قرار می‌دهیم.

کاربرد نمونه

در این بخش یکی از کاربردهای نمونه نمای AdvancedList را در SwiftUI بررسی می‌کنیم.

نکته: کد کامل این پیاده‌سازی را می‌توانید در ریپازیتوری گیت هاب ارائه شده در انتهای راهنما مشاهده کنید. ابتدا باید آیتم‌هایی که می‌خواهیم در لیست دیده شوند را ایجاد کنیم.

آیتم‌های نمونه

ابتدا یک ContactListItem ایجاد کردیم که مخاطبان (نام، نشانی و غیره) را نشان می‌دهد. برای افزودن وهله‌های این آیتم به لیست، باید با پروتکل‌های Identifiable و View سازگار باشد. در اینجا یک کار خاص انجام داده‌ایم. می‌خواهیم این آیتم را بتوانیم به طرز متفاوتی بسته به نوع مشخصه‌اش رندر کنیم. به کاربرد viewRepresentationType در مشخصه body توجه کنید:

 

به علاوه یک آیتم دوم نیز پیاده‌سازی می‌کنیم که یک تبلیغ ساده نمایش می‌دهد. کاری دقیقاً مشابه ContactListItem انجام داده‌ایم. AdListItem یک نوع دارد که تعریف نما را کنترل می‌کند.

 

لیست پیشرفته در SwiftUI

نمای نمونه محتوا

در نهایت به بررسی استفاده از AdvancedList درون یک نمای محتوای ساده می‌پردازیم. شاید کنجکاو باشید که CustomListStateSegmentedControlView چیست. این یک نمای کمکی است که به ما کمک می‌کند به سادگی حالت لیست را تغییر داده و آیتم‌های تصادفی به لیست اضافه کنیم.

 

لیست پیشرفته در SwiftUI

سخن پایانی

به این ترتیب به پایان این مقاله می‌رسیم. از این که این مقاله را مطالعه کردید، متشکریم. امیدواریم نمای AdvancedList را مفید یافته باشید و بتوانید با استفاده از SwiftUI کارهای جالبی انجام دهید. کد کامل موارد مطرح شده در این مقاله را می‌توانید در این ریپوی گیت هاب (+) ملاحظه کنید.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

میثم لطفی (+)

«میثم لطفی» دانش‌آموخته ریاضیات و شیفته فناوری به خصوص در حوزه رایانه است. وی در حال حاضر علاوه بر پیگیری همه علاقه‌مندی‌های خود در رشته‌های برنامه‌نویسی، کپی‌رایتینگ و تولید محتوای چندرسانه‌ای، در زمینه نگارش مقالاتی با محوریت نرم‌افزار نیز با مجله فرادرس همکاری دارد.

آیا این مطلب برای شما مفید بود؟

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *