viewWillDisappear در iOS — ماهیت متد و نحوه استفاده صحیح

نویسنده: IT Sectr منتشر شده: 2026-03-05 زمان مطالعه: 8 دقیقه

viewWillDisappear متدی از UIViewController است که UIKit درست قبل از شروع ناپدید شدن صفحه از نمایشگر کاربر آن را فراخوانی می‌کند. بر اساس Apple Developer Documentation، این متد پارامتر animated را دریافت می‌کند و در هنگام push، pop، present، dismiss و جابجایی تب‌ها فعال می‌شود. viewWillDisappear مکان اصلی برای ذخیره وضعیت و پاکسازی صحیح منابع است.

نکات کلیدی

  • viewWillDisappear قبل از هر بار ناپدید شدن صفحه فراخوانی می‌شود
  • برای ذخیره وضعیت پیش‌نویس‌ها و داده‌های موقت استفاده می‌شود
  • لغو اشتراک از NotificationCenter و KVO — وظیفه اجباری در این متد
  • متد می‌تواند با ژست لغو شده فراخوانی شود — داده‌ها در viewDidDisappear تکرار می‌شوند
  • super.viewWillDisappear برای عملکرد صحیح ناوبری الزامی است

viewWillDisappear چیست

viewWillDisappear متدی از UIViewController است که UIKit درست قبل از شروع ناپدید شدن View کنترلر از صفحه آن را فراخوانی می‌کند. در این لحظه صفحه همچنان برای کاربر قابل مشاهده است، اما انتقال از قبل آغاز شده است: NavigationController انیمیشن push/pop را شروع کرده، پنجره modal شروع به بسته شدن کرده، یا TabBar شروع به جابجایی به تب دیگر کرده است. توسعه‌دهنده این متد را override می‌کند تا عملیاتی را انجام دهد که نیاز به دسترسی به صفحه دارند، در حالی که صفحه برای مخفی شدن آماده می‌شود.

برخلاف viewDidDisappear که پس از مخفی شدن صفحه فعال می‌شود، viewWillDisappear آخرین فرصت را برای ذخیره داده‌ها و آزادسازی منابع فراهم می‌کند، در حالی که کاربر هنوز رابط را می‌بیند. این برای UX حیاتی است — ذخیره پیش‌نویس یا توقف تایمر باید قبل از اینکه کاربر به صفحه دیگری سوئیچ کند اتفاق بیفتد.

متد پارامتر animated را دریافت می‌کند که مشخص می‌کند آیا ناپدید شدن با انیمیشن همراه است یا خیر. مقدار true به این معنی است که UIKit انتقال را با انیمیشن انجام می‌دهد، false — صفحه بلافاصله ناپدید می‌شود، مثلاً در dismiss بدون انیمیشن یا حذف برنامه‌ریزی شده از سلسله‌مراتب.

چه زمانی viewWillDisappear فراخوانی می‌شود

viewWillDisappear در تمام سناریوهایی که صفحه فعلی از حالت فعال خارج می‌شود فراخوانی می‌گردد. موارد اصلی خاص توسعه iOS را بررسی می‌کنیم.

در هنگام push صفحه جدید

وقتی UINavigationController یک کنترلر جدید را push می‌کند، در کنترلر جاری viewWillDisappear در ابتدای انیمیشن انتقال فراخوانی می‌شود. در این لحظه صفحه فعلی هنوز قابل مشاهده است و کنترلر جدید روی آن اسلاید می‌شود. این سناریوی استانداردی است که در آن viewWillDisappear با animated = true فعال می‌شود.

در هنگام pop صفحه فعلی

وقتی کاربر دکمه برگشت را فشار می‌دهد یا یک سوایپ تعاملی به عقب انجام می‌دهد، در کنترلر جاری viewWillDisappear فراخوانی می‌شود. در ژست تعاملی، این فراخوانی ممکن است لغو شود اگر کاربر نظرش را عوض کرده و صفحه را به جای خود بازگرداند. این ویژگی مهمی است که در طراحی ذخیره وضعیت باید در نظر گرفته شود.

swift
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    saveDraftData()
    NotificationCenter.default.removeObserver(self)
}

در هنگام dismiss کنترلر

هنگام بستن پنجره modal، viewWillDisappear روی کنترلر در حال بسته شدن در ابتدای انیمیشن dismiss فراخوانی می‌شود. در این لحظه می‌توان نتایج را از طریق delegate یا closure بازگرداند، زیرا کنترلری که پنجره modal را ارائه کرده هنوز کنترل را دریافت نکرده است.

در هنگام جابجایی تب‌های TabBar

UITabBarController viewWillDisappear را روی کنترلر تب ترک شده بلافاصله پس از لمس تب دیگر توسط کاربر فراخوانی می‌کند. اگر در تب فعلی فرآیندهای فعالی وجود دارد — پخش رسانه، بارگذاری فایل، تایمر — در اینجا آنها متوقف یا معلق می‌شوند.

کاربردهای عملی در viewWillDisappear

viewWillDisappear وظایف مشخصی را در مدیریت منابع و وضعیت حل می‌کند. سناریوهای کلیدی را با مثال‌های کد بررسی می‌کنیم.

ذخیره داده‌های کاربر

مهمترین وظیفه viewWillDisappear — ذخیره داده‌هایی است که کاربر در صفحه فعلی وارد یا تغییر داده است. پیش‌نویس پیام‌ها، فیلدهای فرم ویرایش شده، تنظیمات انتخاب شده — همه اینها باید قبل از ناپدید شدن صفحه ذخیره شوند. برای ماندگاری از Core Data، UserDefaults یا ذخیره‌سازی فایل استفاده کنید.

swift
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    guard hasUnsavedChanges else { return }
    draftStorage.save(currentDraft)
}

لغو اشتراک از اعلان‌ها

NotificationCenter، KVO و Combine publisherهایی که در viewWillAppear یا viewDidLoad مشترک شده‌اید باید در viewWillDisappear لغو شوند. اگر این کار را نکنید، اعلان‌ها به صفحه مخفی ارسال می‌شوند و باعث به‌روزرسانی‌های UI می‌شوند که کاربر نمی‌بیند، یا بدتر — crashes به دلیل ارجاع به اشیاء آزاد شده.

توقف انیمیشن‌ها و تایمرها

انیمیشن‌های UIView که در viewDidAppear شروع شده‌اند و تایمرهایی که از طریق Timer یا DispatchSource کار می‌کنند باید در viewWillDisappear متوقف شوند. ادامه انیمیشن‌ها در صفحه مخفی GPU و باتری را بدون هیچ فایده‌ای برای کاربر مصرف می‌کند. آنها را به صراحت متوقف کنید — با فراخوانی invalidate برای تایمرها و removeAllAnimations برای لایه‌ها.

swift
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    countdownTimer?.invalidate()
    countdownTimer = nil
    loadingIndicator.layer.removeAllAnimations()
}

بازگرداندن داده‌ها

اگر کنترلر برای دریافت نتیجه باز شده است — انتخاب عنصر، ورود متن، تأیید عمل — viewWillDisappear آخرین لحظه‌ای است که کنترلر اصلی همچنان در پشته وجود دارد و می‌تواند داده‌ها را دریافت کند. delegate یا closure را قبل از فراخوانی deinit صدا بزنید.

استراتژی ذخیره وضعیت

ذخیره مطمئن وضعیت صفحه یکی از دشوارترین وظایف در توسعه iOS است. viewWillDisappear عنصر مهم اما نه تنها عنصر استراتژی است. رویکرد جامع را بررسی می‌کنیم.

سطح 1 — ذخیره در viewWillDisappear. ذخیره سریع داده‌های سبک که باید بلافاصله پس از بازگشت در دسترس باشند. مناسب برای وضعیت UI: موقعیت اسکرول، بخش انتخاب شده، متن در فیلدهای ورودی. مشکل: در ژست تعاملی pop لغو شده، ذخیره اتفاق می‌افتد اگرچه کاربر در صفحه باقی مانده است — داده‌ها بدون نیاز بازنویسی می‌شوند.

سطح 2 — ذخیره در viewDidDisappear. ذخیره سطح اول را تکرار می‌کند، اما تنها پس از اطمینان از مخفی شدن صفحه فعال می‌شود. این بیمه در برابر ژست‌های لغو شده است. با این حال، اگر در viewWillDisappear قبلاً از اعلان‌ها لغو اشتراک کرده‌اید، viewDidDisappear ممکن است به برخی داده‌ها دسترسی نداشته باشد.

سطح 3 — ذخیره از طریق اعلان‌های برنامه. UIApplication.willResignActiveNotification و UIApplication.didEnterBackgroundNotification جمع‌شدن برنامه را رهگیری می‌کنند. اگر کاربر برنامه را جمع کرده باشد، viewWillDisappear ممکن است فراخوانی نشده باشد — اما ذخیره از طریق این اعلان‌ها تضمین می‌کند یکپارچگی داده‌ها در پایان جلسه.

سطحمتد/اعلانقابلیت اطمینانکاربرد
1viewWillDisappearزیادوضعیت UI، پیش‌نویس‌ها
2viewDidDisappearبسیار زیادداده‌های حیاتی
3willResignActiveحداکثرهنگام جمع‌شدن

توصیه: برای داده‌های حیاتی کاربر از ترکیب هر سه سطح استفاده کنید. برای وضعیت غیرحیاتی — سطح اول کافی است. مهم است که داده‌های مشابه را چندین بار بازنویسی نکنید — از flag dirty استفاده کنید که نشان می‌دهد داده‌ها از آخرین ذخیره تغییر کرده‌اند.

توجه ویژه باید به استراتژی برای صفحات CRUD شود، جایی که کاربر داده وارد می‌کند. در چنین صفحاتی ذخیره هر فشردن کلید در viewWillDisappear توصیه نمی‌شود — این اضافی است. از ذخیره خودکار با تأخیر (debounce) از طریق Timer استفاده کنید و viewWillDisappear را فقط برای ذخیره نهایی اجباری در صورت وجود تغییرات ذخیره نشده به کار ببرید. چنین رویکردی بین عملکرد و ایمنی داده‌ها تعادل ایجاد می‌کند.

برای برنامه‌های دارای Core Data اقدام اضافی فراخوانی saveContext در viewWillDisappear فقط در صورت وجود تغییرات واقعی در managed object context است. بررسی context.hasChanges قبل از ذخیره از نوشته‌های اضافی در persistent store جلوگیری می‌کند و عمر باتری دستگاه را افزایش می‌دهد. این بررسی را با ذخیره‌سازی سراسری در applicationDidEnterBackground ترکیب کنید.

خطاهای رایج در viewWillDisappear

استفاده نادرست از viewWillDisappear می‌تواند منجر به از دست رفتن داده‌ها، نشت حافظه و رفتار ناپایدار برنامه شود. خطاهای رایج توسعه‌دهندگان iOS را بررسی می‌کنیم.

خطای اول — ذخیره داده‌ها فقط در viewWillDisappear. همانطور که در بالا بحث شد، در ژست تعاملی pop متد حتی اگر صفحه ناپدید نشود فراخوانی می‌شود. اگر ذخیره عوارض جانبی دارد — ارسال داده به سرور، تغییر وضعیت — این می‌تواند منجر به فعال‌سازی‌های کاذب شود. بررسی isBeingDismissed یا isMovingFromParent را اضافه کنید.

خطای دوم — عدم لغو اشتراک از NotificationCenter. این یکی از رایج‌ترین نشت‌های حافظه در iOS است. اگر در viewWillAppear مشترک UIResponder.keyboardWillShowNotification شده‌اید اما در viewWillDisappear لغو اشتراک نکرده‌اید، closure به فراخوانی ادامه می‌دهد. هنگام deinit کنترلر، closure به شیء آزاد شده ارجاع می‌دهد — crash برنامه تضمین شده است.

خطای سوم — اجرای عملیات سنگین同步. ذخیره حجم زیادی از داده‌ها، نوشتن در Core Data یا سیستم فایل در viewWillDisappear main thread را مسدود می‌کند. اگر عملیات طولانی‌تر از انیمیشن انتقال باشد، UIKit thread را متوقف می‌کند و رابط قفل می‌شود. ذخیره‌سازی‌های سنگین را به صف‌های پس‌زمینه منتقل کنید.

خطای چهارم — فراموش کردن فراخوانی super. عدم فراخوانی super.viewWillDisappear می‌تواند عملکرد UINavigationController و UITabBarController را مختل کند، زیرا آنها از این متد برای وضعیت‌های داخلی خود استفاده می‌کنند. همیشه super را مطابق مستندات Apple اول یا آخر فراخوانی کنید.

این مشکل در iOS با چندوظیفگی فعال و جابجایی بین برنامه‌ها تشدید می‌شود. خطای پنجم — استفاده از DispatchQueue.main.async پس از ذخیره در viewWillDisappear. اگر پس از فراخوانی super.viewWillDisappear یک بلوک به صورت ناهمگام به صف اصلی ارسال کنید، تضمینی برای وجود کنترلر در زمان اجرای بلوک وجود ندارد. همیشه از مراجع ضعیف [weak self] در داخل closureها برای جلوگیری از ارجاع به حافظه آزاد شده و جلوگیری از crash برنامه استفاده کنید.

سوالات متداول

تفاوت viewWillDisappear با viewDidDisappear چیست؟

viewWillDisappear در ابتدای ناپدید شدن، زمانی که صفحه هنوز قابل مشاهده است، فراخوانی می‌شود. viewDidDisappear — پس از اینکه صفحه کاملاً مخفی شد و انیمیشن به پایان رسید.

در ژست pop لغو شده چه باید کرد؟

برای تأیید ذخیره از viewDidDisappear استفاده کنید یا ویژگی‌های isMovingFromParent و isBeingDismissed را در viewWillDisappear بررسی کنید تا مشخص شود آیا صفحه واقعاً ناپدید می‌شود یا خیر.

آیا لغو اشتراک از NotificationCenter به صورت دستی لازم است؟

بله، حتماً، اگر از بلوک‌ها یا selectorها با self استفاده می‌کنید. ARC اشتراک‌های NotificationCenter را مدیریت نمی‌کند. در iOS 9+ برای بلوک‌ها از مرجع ضعیف استفاده کنید و در viewWillDisappear لغو اشتراک کنید.

چگونه داده‌ها را در force quit از طریق viewWillDisappear ذخیره کنیم؟

به هیچ وجه — force quit متدهای Lifecycle را فراخوانی نمی‌کند. برای ذخیره تضمینی در پایان برنامه از UIApplication.willTerminateNotification استفاده کنید یا داده‌ها را در زمان واقعی با تغییر آنها ذخیره کنید.

آیا viewWillDisappear می‌تواند زمانی که کنترلر ناپدید نمی‌شود فراخوانی شود؟

بله، در ژست تعاملی pop، UIKit viewWillDisappear را بلافاصله پس از شروع ژست فراخوانی می‌کند. اگر کاربر ژست را لغو کند، صفحه قابل مشاهده می‌ماند، اما متد قبلاً فعال شده است. همیشه isMovingFromParent را بررسی کنید.

خلاصه

  • viewWillDisappear قبل از هر ناپدید شدن صفحه فراخوانی می‌شود — در push، pop، present و dismiss
  • هدف اصلی — ذخیره وضعیت، لغو اشتراک از اعلان‌ها و توقف انیمیشن‌ها
  • در ژست‌های تعاملی، متد ممکن است بدون مخفی شدن واقعی صفحه فراخوانی شود
  • برای داده‌های حیاتی کاربر از استراتژی ذخیره سه‌سطحی استفاده کنید
  • لغو اشتراک از NotificationCenter در viewWillDisappear از نشت حافظه جلوگیری می‌کند
  • عملیات سنگین同步 main thread را مسدود می‌کند — آنها را به صف‌های پس‌زمینه منتقل کنید
  • همیشه super.viewWillDisappear را برای حفظ ناوبری صحیح فراخوانی کنید

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید