viewWillAppear — این متدی از UIViewController است که UIKit هر بار قبل از اینکه صفحه برای کاربر قابل مشاهده شود، آن را فراخوانی میکند. بر اساس Apple Developer Documentation، این متد یک پارامتر بولی animated دریافت میکند که نشان میدهد آیا انتقال با انیمیشن همراه است یا خیر. viewWillAppear — مکان اصلی برای بهروزرسانی دادهها و همگامسازی وضعیت صفحه است.
نکات اصلی
viewWillAppear — این متدی از UIViewController است که UIKit درست قبل از افزودن View به سلسلهمراتب پنجرهها آن را فراخوانی میکند. در این لحظه View پس از مراحل Auto Layout ابعاد نهایی خود را دارد، اما هنوز برای کاربر قابل مشاهده نیست — انیمیشن انتقال یا شروع نشده یا در حال اجراست. توسعهدهنده این متد را برای انجام عملیاتی که باید قبل از هر بار نمایش صفحه انجام شوند، بازنویسی میکند.
بر خلاف viewDidLoad که یک بار اجرا میشود، viewWillAppear هر بار که صفحه قرار است ظاهر شود فراخوانی میشود: در باز شدن اولیه، هنگام بازگشت از کنترلر فرزند، پس از بستن پنجره مودال و هنگام تغییر تبهای TabBar. این آن را به روشی کلیدی برای حفظ وضعیت بهروز رابط کاربری تبدیل میکند.
متد پارامتر animated از نوع Bool را دریافت میکند که اگر ظاهر شدن صفحه با انیمیشن همراه باشد true است. انتقال این پارامتر به متدهای NavigationBar و TabBar که پارامتر مشابهی برای رفتار هماهنگ دارند راحت است.
زمانبندی فراخوانی viewWillAppear به نوع ناوبری بستگی دارد، اما قانون کلی ثابت است: متد قبل از قابل مشاهده شدن View اجرا میشود. سناریوهای اصلی را بررسی میکنیم.
پس از فراخوانی viewDidLoad، UIKit آمادهسازی برای نمایش را آغاز میکند: View به سلسلهمراتب اضافه میشود، مراحل layout اجرا میشوند و درست قبل از شروع انیمیشن انتقال، viewWillAppear فراخوانی میشود. در این لحظه صفحه هنوز قابل مشاهده نیست، اما همه subviews ابعاد صحیح دارند و میتوان محتوای آنها را با خیال راحت بهروزرسانی کرد.
وقتی کاربر دکمه بازگشت را فشار میدهد یا به صورت برنامهنویسی popViewController را فراخوانی میکند، UIKit به صفحه قبلی بازمیگردد و viewWillAppear آن را فراخوانی میکند. این سناریوی اصلی برای استفاده از viewWillAppear است — بهروزرسانی لیست پس از افزودن عنصر یا همگامسازی تنظیمات.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
updateBadgeCount()
}
پس از بستن کنترلری که به صورت مودال ارائه شده، UIKit viewWillAppear را در کنترلری که آن را ارائه کرده فراخوانی میکند. این سناریو نیاز به توجه ویژه دارد اگر از delegateها یا closureها برای بازگرداندن دادهها استفاده میکنید — viewWillAppear تضمین میکند که صفحه پس از دریافت نتیجه بهروزرسانی شود.
TabBarController هر بار که تب تغییر میکند viewWillAppear را در کنترلر تب انتخاب شده فراخوانی میکند. اگر در تب دادههای پویا نمایش داده میشوند — نرخ ارز، اعلانها، وضعیت کاربر — viewWillAppear مکان ایدهآلی برای بهروزرسانی آنهاست.
viewWillAppear چندین وظیفه مشخص را حل میکند که در روشهای دیگر قابل انجام نیستند یا بهینه نیستند. اصلیترین آنها را بررسی میکنیم.
رایجترین کاربرد viewWillAppear — بارگذاری مجدد UITableView یا UICollectionView در هر بار ظاهر شدن صفحه. اگر دادهها در صفحه قبلی تغییر کرده باشند (افزودن عنصر، تغییر وضعیت)، فراخوانی reloadData در viewWillAppear تضمین میکند که کاربر اطلاعات بهروز میبیند.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
viewModel.synchronize()
tableView.reloadData()
}
در viewWillAppear میتوان ظاهر NavigationBar را به راحتی پیکربندی کرد: مخفی یا نمایش آن، تغییر رنگ، تنظیم large title. اگر NavigationBar در صفحات مختلف ظاهر متفاوتی دارد، viewWillAppear مکان مناسبی برای این تغییرات است، زیرا viewDidLoad فقط یک بار فراخوانی میشود.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.setNavigationBarHidden(
false, animated: animated
)
navigationController?.navigationBar.prefersLargeTitles = true
tabBarController?.tabBar.isHidden = false
}
اعلانهایی که فقط زمانی که صفحه قابل مشاهده است معنا دارند — صفحهکلید، اعلانهای تغییر محتوا — در viewWillAppear اشتراک و در viewDidDisappear لغو میشوند. این کار از handlerهای اضافی در زمانی که صفحه فعال نیست جلوگیری میکند و از نشت حافظه محافظت میکند.
اگر صفحه ممکن است توسط برنامه مخفی یا کوچک شود، viewWillAppear مکان مناسبی برای بازگردانی وضعیت UI است: تغییر بخشها، بازگردانی موقعیت اسکرول، بازنشانی تغییرات موقت. کاربر صفحه را در هر بار ظاهر شدن به شکلی قابل پیشبینی دریافت میکند.
در صفحاتی که شمارندههای پیامهای خوانده نشده، رتبهبندیها یا اعلانها را نمایش میدهند، viewWillAppear مکان مناسبی برای بهروزرسانی آنهاست. اگر کاربر ممکن است تعداد را در صفحه دیگری تغییر داده باشد، در اینجا محاسبه مجدد و بهروزرسانی UITabBarItem.badgeValue یا نشانگرهای سفارشی فراخوانی میشود. این تضمین میکند که کاربر بدون توجه به مدت زمانی که در صفحات دیگر بوده، همیشه اعداد بهروز را میبیند.
به طور جداگانه باید به کار با collectionView اشاره کرد: اگر دادههای صفحه در قالب شبکهای با سلولهای حاوی شمارنده یا وضعیت نمایش داده میشوند، بهروزرسانی آنها در viewWillAppear باید انتخابی باشد. به جای reloadData کامل، از reloadItemsAtIndexPaths برای سلولهای قابل مشاهده استفاده کنید تا از چشمک زدن و از دست رفتن موقعیت اسکرول جلوگیری شود.
درک تفاوت بین viewWillAppear و viewDidLoad — اساس معماری صحیح UIViewController است. این روشها فرکانس فراخوانی، زمینه و هدف متفاوتی دارند.
viewDidLoad یک بار فراخوانی میشود و برای پیکربندی که در طول زمان تغییر نمیکند مناسب است: ثبت سلولها، تنظیم delegateها، مقداردهی اولیه ثابتها. viewWillAppear در هر بار ظاهر شدن فراخوانی میشود و برای عملیاتی که باید تکرار شوند مناسب است: بهروزرسانی دادهها، پیکربندی عناصر قابل مشاهده، همگامسازی وضعیت.
| ویژگی | viewDidLoad | viewWillAppear |
|---|---|---|
| تکرار | یک بار | هر بار هنگام ظاهر شدن |
| View قابل مشاهده | خیر | خیر (به زودی قابل مشاهده میشود) |
| ابعاد View | نهایی نیست | نهایی |
| مناسب برای | پیکربندی یک بار | بهروزرسانی و همگامسازی |
| انیمیشن | قابل اجرا نیست | پارامتر animated |
قاعده طلایی: اگر عملیات باید فقط یک بار انجام شود — در viewDidLoad قرار دهید. اگر هر بار پس از بازگشت به صفحه — در viewWillAppear قرار دهید.
استفاده نادرست از viewWillAppear میتواند منجر به مشکلات عملکرد، بهروزرسانیهای اضافی و وضعیت ناسازگار رابط کاربری شود. رایجترین خطاها را بررسی میکنیم.
خطای اول — تکرار منطق viewDidLoad. اگر سلولهای جدول را هم در viewDidLoad و هم در viewWillAppear ثبت میکنید — ثبت چندین بار انجام میشود، در حالی که پیکربندی یک بار کافی است. همه پیکربندیهای یک بار را به viewDidLoad منتقل کنید.
خطای دوم — reloadData بیقید و شرط در هر بار ظاهر شدن. اگر دادهها تغییر نکرده باشند، بارگذاری مجدد جدول باعث درخواستهای اضافی از data source و ترسیم مجدد سلولها میشود و عملکرد را کاهش میدهد. قبل از فراخوانی reloadData بررسی کنید که آیا وضعیت واقعاً تغییر کرده است.
خطای سوم — کار با درخواستهای شبکه بدون در نظر گرفتن اینکه صفحه ممکن است قبل از تکمیل درخواست دوباره مخفی شود. اگر در viewWillAppear یک درخواست URLSession راهاندازی میکنید و کاربر بلافاصله به صفحه دیگری میرود، نتیجه ممکن است به View مخفی شده اعمال شود. از وظایف قابل لغو استفاده کنید یا قبل از بهروزرسانی isViewLoaded و window را بررسی کنید.
خطای چهارم — فراموش کردن فراخوانی super. عدم فراخوانی super.viewWillAppear میتواند عملکرد کنترلرهای والد (UINavigationController، UITabBarController) را مختل کند و منجر به پردازش نادرست حرکات و انتقالها شود. super باید همیشه فراخوانی شود.
خطای پنجم — تغییر constraintها بدون فراخوانی layoutIfNeeded. اگر در viewWillAppear به صورت برنامهنویسی constraints را تغییر میدهید، UIKit آنها را فوراً اعمال نمیکند — تغییرات تا مرحله layout بعدی جمع میشوند. برای اعمال فوری تغییرات پس از تغییر constraintها، view.layoutIfNeeded() را فراخوانی کنید. این به ویژه هنگام تنظیم ارتفاع عناصر وابسته به محتوا مهم است.
خطای ششم — تلاش برای اجرای انیمیشن در viewWillAppear. همانطور که در بالا ذکر شد، UIKit هنوز در حال پردازش انیمیشن انتقال است و انیمیشن شما ممکن است با انیمیشن سیستم رقابت کند. اگر نیاز دارید عنصری با افکت ظاهر شود، از انیمیشن ورودی در viewDidAppear استفاده کنید و در viewWillAppear فقط وضعیت اولیه را پیکربندی کنید: شفافیت 0، transform در مقیاس 0.8 و غیره.
خطای هفتم — نادیده گرفتن پارامتر animated. برخی توسعهدهندگان مقدار animated را در viewWillAppear بررسی نمیکنند و عملیاتی را انجام میدهند که باید به وجود انیمیشن وابسته باشد. به عنوان مثال، مخفی کردن NavigationBar با animated = false میتواند بدون انیمیشن انجام شود و با animated = true — با انیمیشن، تا انتقال روان به نظر برسد. همیشه پارامتر animated را به روشهای مربوطه UIKit منتقل کنید.
خطای هشتم — تغییر UI در صفحه غیرقابل مشاهده. اگر در viewWillAppear یک درخواست شبکه راهاندازی میکنید و بلاک تکمیل آن UI را بهروزرسانی میکند در حالی که صفحه ممکن است ناپدید شده باشد، کاربر چشمک زدن یا وضعیت ناسازگار را میبیند. همیشه قبل از بهروزرسانی UI در closureها isViewLoaded و window را بررسی کنید. این اقدام ساده از crashها و ترسیم مجدد اضافی رابط جلوگیری میکند.
سوالات متداول
viewWillAppear قبل از شروع انیمیشن ظاهر شدن، زمانی که View هنوز قابل مشاهده نیست، فراخوانی میشود. viewDidAppear — پس از پایان انیمیشن، زمانی که صفحه کاملاً نمایش داده شده و برای تعامل در دسترس است.
در شرایط عادی viewWillAppear همیشه هنگام ظاهر شدن صفحه فراخوانی میشود. استثنا — بستن اجباری برنامه (force quit) که در آن UIKit فرصت فراخوانی روشهای Lifecycle را ندارد.
بله، حتماً. UIKit از این فراخوانی برای هماهنگی داخلی با UINavigationController و UITabBarController استفاده میکند. بدون super ممکن است حرکات و انیمیشنهای انتقال خراب شوند.
در هر بار تغییر تب. UIKit به محض اینکه کاربر آیکون مربوطه را در TabBar لمس کند، viewWillAppear را در کنترلر تب انتخاب شده فراخوانی میکند.
از ویژگیهای کنترلر یا data source مشترک استفاده کنید. قبل از فراخوانی popViewController مقادیر مورد نیاز را در کنترلر قبلی تنظیم کنید و در viewWillAppear آن در دسترس خواهند بود.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید