نکات و ترفندهای SwiftUI | راهنمای مقدماتی
SwiftUI روش ساخت رابطهای کاربری را برای اپلیکیشنهای iOS متحول ساخته است. این فریمورک مبتنی بر حالت و اعلانی یک روش مسنجم و آسان ارائه میکند که به طور عمده ناشی از تابعسازهایی است که زبان DSL این فریمورک را تشکیل دادهاند. در این مقاله با برخی از نکات و ترفندهای SwiftUI آشنا خواهیم شد.
SwiftUI قابلیتها و امکانات زیادی دارد و در این راهنما تلاش میکنیم برخی از موارد مهم را صرفاً به صورت اجمالی معرفی کنیم. به این ترتیب در بخشهای بعدی برخی نکات و ترفندها را که به ساخت آسانتر اپلیکیشنهای SwiftUI کمک میکنند با هم مرور خواهیم کرد.
قرار دادن نماها درون AnyView یا Groups
کلیدواژه some در سوئیفت 5.1 برای تعریف کردن انواع مبهم معرفی شده است. این نوع به کامپایلر اجازه میدهد که در مورد نوع صحیح تابع بر اساس مقدار بازگشتی تصمیمگیری کند.
با این که این قابلیت برای کدهای تک شاخه یا زمانی که انواع نماها مشابه هستند مفید است، اما در مواردی که کدهای با چند شاخه داشته باشید و یا نماها متفاوت باشند، موجب بروز خطای کامپایلر خواهد شد.
به طور خاص رابط SwiftUI نمیتواند یک نوع مبهم منفرد را تشخیص دهد. ما میتوانیم این مشکل را با قرار دادن مجموعه نماها در یک Group یا AnyView حل کنیم. AnyView ما را مطمئن میسازد که یک نوع بازگشتی مبهم منفرد وجود دارد، اما نباید از آن استفاده بیش از حد بکنید.
نکته فوق در مواردی که از گزارههای سوئیچ در بدنه SwiftUI استفاده میکنید نیز مفید است. با این حال، جایگزین بهتر در چنین مواردی این است که گزاره سوئیچ را در یک تابع مجزا بیاورید.
اجتناب از بارگذاری مجدد کل بدنه SwiftUI
SwiftUI یک فریمورک مبتنی بر حالت است و از این رو هر زمان که حالتی تغییر یابد، همه نماها در بدنه SwiftUI رفرش میشوند. این موضوع شامل آنهایی که به حالت وابسته نیستند نیز میشود.
برخی اوقات، ممکن است بخواهید روشی برای جلوگیری از رفرش شدن کل بدنه در اختیار داشته باشید. خوشبختانه این کار همانند مثال زیر از طریق جداسازی نماهایی که به حالت وابسته نیستند میسر شده است.
در کد فوق، RandomText دیگر در مواردی که شیت انتهایی نمایش یافته یا پنهان شود، متن خود را رفرش نمیکند.
کوتاه نگه داشتن بلوک کد init در نماهای سفارشی
باید اشاره کنیم که سازنده نماهای سفارشی در بدنه SwiftUI هر زمان که نماهای بالادستی رفرش شوند، فراخوانی میشود. با این حال، این به آن معنی نیست که کل نمای سفارشی از نو ساخته میشود.
برای نمونه یک نمای دوربین سفارشی SwiftUI بلوک init خود را هر بار فراخوانی میکند، اما نشستهای دریافت AVFoundation را هر بار از نو نمیسازد، مگر این که یک «پوشش مشخصه» (property wrapper) حالت به آن ارسال کرده و تغییری را در آن تریگر کنید. بدین ترتیب مطمئن میشویم که بلوک کد init زیاد سنگین نیست.
از تصاویر SwiftUI به روش مؤثر استفاده کنید
iOS 13 همراستا با SwiftUI نمادهای SF را معرفی کرده است که مجموعهای از تصاویر را عرضه میکنند. امکان سفارشیسازی آنها در تصاویر SwiftUI به سادگی با استفاده از مادیفایرهایی از قبیل font وجود دارد. این کار به همان روش Text در SwiftUI انجام میپذیرد.
بهرهگیری از درونیابی
در اغلب اوقات ما تصاویری داریم که باید محتوایشان به اندازهای بزرگتر کشیده شوند. در این صورت ممکن است در نهایت تصاویر تاری به دست آید، چون درونیابی (interpolation) که به صورت پیشفرض اجرا میشود، پیکسلها را در هم ترکیب میکند. با تنظیم مادیفایر interpolation روی مقدار none میتوانیم مطمئن باشیم که این ترکیب شدن اتفاق نمیافتد و تصویر پیکسلاته شده ظاهر مناسبی دارد.
کار با تصاویر در NavigationView
یکی از موارد مهم در زمان کار با تصاویر در SwiftUI مواردی است که میخواهیم تصویر را در یک قرار دهیم. به صورت پیشفرض، تصاویر یک ماسک رنگمایه میگیرند که در زمان قرارگیری در NavigationView آنها را به رنگ آبی درمیآورد. برای اجتناب از این حالت باید .buttonStyle(PlainButtonStyle()) را روی NavigationLink مانند مثال زیر تنظیم کنیم:
خروجی (ها) با و بدون تنظیم PlainButtonStyle روی NavigationLink به صورت زیر هستند:
مدیریت پیشنمایشهای چندگانه
میدانیم که SwiftUI پیشنمایشهای آنی ارائه میکند، اما نکته جالبتر این است که امکان مشاهده چندین پیشنمایش به صورت همزمان وجود دارد که میتواند شامل نمایش حالت تیره یا وضعیت ظاهری روی دستگاههای متفاوت باشد. در ادامه مثالی از یک نمای SwiftUI را در حالتهای روشن و تیره مشاهده میکنید:
حالت تیره در پیشنمایشها به صورت پیشفرض کارکرد نصفهای دارد. شما میتوانید به جای تعیین رنگ پسزمینه سیستم مانند تصویر فوق از یک اکستنشن مادیفایر به عنوان راهحل استفاده کنید. همچنین میتوانید پیشنمایشهای محتوا را گروهبندی کرده و یا از یک حلقه forEach استفاده کنید که دستگاههای مختلف UI را مانند تصویر زیر نمایش میدهد:
بهرهگیری از مادیفایر Frame برای پر کردن نماها
نماها به طور پیشفرض فضای کمی را روی صفحه اشغال میکنند. برای نمونه TextView زیر را ببینید:
برای باز کردن نماها و پر کردن فضای نمای بالادستی میتوانیم از مادیفایر Frame استفاده کنیم و فضای نمای بالادستی را پر کنیم. با استفاده از مادیفایر Frame و تعیین مشخصههای maxWidth و maxHeight روی مقدار infinity مانند مثال زیر این کار انجام شدنی است:
استفاده از مادیفایرها و اکستنشنهای سفارشی
با بهرهگیری از اکستنشنهای سفارشی میتوانیم کارکردهای داخلی را بسط دهیم و از طریق آن کد خود را ساده کرده و خوانایی کد را بهبود بخشیم. برای نمونه قرار دادن نماها در یک AnyView یا جاسازی آنها در NavigationView یک رویه رایج است. به این ترتیب میتوانیم اکستنشنهایی برای آنها به صورت زیر بسازیم:
با در نظر گرفتن مثال فوق، میتوانیم یک اکستنشن برای تصاویر SwiftUI ایجاد کرده و همچنین یک تصویر placeholder پیشفرض بسازیم.
SwiftUI طیفی از مادیفایرهای نما را در اختیار ما قرار میدهد که میتوانند به صورت بلوکهای سازنده به همدیگر متصل شوند. اما گاهی اوقات به خصوص در زمان سفارشیسازی نماها، در نهایت یک مجموعه مادیفایرهای یکسان به دست میآید. به این ترتیب کدهای تکراری ایجاد میشود. برای اجتناب از این وضعیت میتوانید از مادیفایرهای سفارشی نما استفاده کنید. کد زیر یکی از این مادیفایرهای نما را نشان میدهد که یک استایل سفارشی ایجاد میکند.
سخن پایانی
در این مقاله برخی از نکات و ترفندهای SwiftUI را توضیح دادیم که به افزایش سرعت و سهولت توسعه کد کمک میکند. در این بخش به یک ترفند مهم دیگر نیز اشاره میکنیم. گاهی اوقات بروز یک خطا در SwiftUI موجب توقف پیشنمایش میشود و باید دکمه Resume را مجدداً بفشاریم. از آنجا که این حالت مکرر رخ میدهد، بهتر است بدانید که با فشردن کلیدهای ترکیبی Option+Cmd+P میتوانید به سرعت کار را از سر بگیرید.