viewDidDisappear — UIViewController کے لائف سائیکل کا وہ طریقہ ہے جو iOS ڈیوائس کی اسکرین سے ویو کے مکمل غائب ہونے کے فوراً بعد کال ہوتا ہے۔ ڈیولپرز اسے اینیمیشنز روکنے، رینڈم ایکسیس میموری خالی کرنے، نوٹیفیکیشنز سے ان سبسکرائب ہونے اور موجودہ حالت محفوظ کرنے کے لیے استعمال کرتے ہیں۔ Apple Developer Documentation (2025) کے مطابق، اس طریقہ کا درست نفاذ فعال نیویگیشن والی ایپلی کیشنز میں 40% تک میموری لیک کو روکتا ہے۔ اس کے بیک گراؤنڈ میں ہونے والے عمل بیٹری اور پروسیسر کے وسائل استعمال کرتے رہ سکتے ہیں۔ viewDidDisappear کا درست استعمال iOS ڈیولپر کی کلیدی مہارتوں میں سے ایک ہے جو براہ راست ایپلی کیشن کی کارکردگی اور استحکام کو متاثر کرتا ہے۔
اہم نکات
viewDidDisappear — UIViewController سپرکلاس کا ایک ہک طریقہ ہے جسے سسٹم اس وقت کال کرتا ہے جب ویو (view) اسکرین پر ونڈو کے درجہ بندی سے مکمل طور پر ہٹا دیا جاتا ہے۔ یہ UIKit میں view کے معیاری لائف سائیکل کا حصہ ہے اور ڈیولپر کو اختتامی کارروائیاں انجام دینے کے لیے ایک نقطہ فراہم کرتا ہے۔
یہ طریقہ UIViewController پروٹوکول میں اعلان کردہ ہے اور تمام ذیلی کلاسز میں اوور رائیڈ کرنے کے لیے دستیاب ہے۔ طریقہ کی سگنیچر: override func viewDidDisappear(_ animated: Bool)۔ animated پیرامیٹر بتاتا ہے کہ آیا ٹرانزیشن اینیمیشن کے ساتھ تھی۔ یہ پروگرامیٹک اور اینیمیٹڈ ٹرانزیشنز میں فرق کرنے کی اجازت دیتا ہے تاکہ رویے کو زیادہ درست طریقے سے کنٹرول کیا جا سکے۔
viewWillDisappear کے برعکس، جو اینیمیشن شروع ہونے سے پہلے کال ہوتا ہے، viewDidDisappear اس بات کی ضمانت دیتا ہے کہ view صارف کو نظر نہیں آ رہا ہے۔ یہ ان کارروائیوں کے لیے اہم ہے جو صرف انٹرفیس کے مکمل چھپنے کے بعد انجام دی جانی چاہئیں — مثال کے طور پر، فل سکرین اوورلے عناصر کو چھپانا یا ویڈیو ریکارڈنگ مکمل کرنا۔
یہ طریقہ بیس کلاس UIViewController میں متعین ہے اور اس کی سگنیچر مندرجہ ذیل ہے:
import UIKit
class MyViewController: UIViewController {
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
// وسائل کی آزادی اور ان سبسکرائب ہونا
}
}
نفاذ کی پہلی لائن میں super.viewDidDisappear(animated) کا لازمی کال — UIKit کی ضرورت ہے۔ اس کے بغیر سپرکلاس view کی نمائش سے متعلق اندرونی عمل کو درست طریقے سے مکمل نہیں کر سکے گا۔ اس اصول کو نظر انداز کرنا نیویگیشن کے غیر متوقع رویے اور ممکنہ خرابیوں کا باعث بنتا ہے۔
UIViewController کا مکمل لائف سائیکل چھ کلیدی طریقوں پر مشتمل ہے، جن میں سے ہر ایک view کے وجود کے ایک مخصوص مرحلے کے لیے ذمہ دار ہے۔ viewDidDisappear چھپنے کی ترتیب کو مکمل کرتا ہے، viewWillDisappear کے بعد آتا ہے۔ تمام طریقوں کے کال ہونے کی ترتیب کو سمجھنا ضروری ہے تاکہ وسائل کی ابتدا اور آزادی کو درست طریقے سے تقسیم کیا جا سکے۔
view کے ظاہر ہونے پر ترتیب: viewDidLoad → viewWillAppear → viewDidAppear۔ چھپنے پر: viewWillDisappear → viewDidDisappear۔ آخری مرحلہ — deinit، جو UIViewController آبجیکٹ کے خاتمے پر کال ہوتا ہے۔ یہ چھ طریقے ایک مکمل دور بناتے ہیں جو حالت کے قابل پیشن گوئی انتظام کی ضمانت دیتا ہے۔
| طریقہ | کال ہونے کا لمحہ | عام استعمال |
|---|---|---|
| viewDidLoad | view کے میموری میں لوڈ ہونے کے بعد | UI کی ابتدائی ترتیب، ڈیٹا پر سبسکرائب ہونا |
| viewWillAppear | view کے اسکرین پر ظاہر ہونے سے پہلے | ظاہر کرنے سے پہلے ڈیٹا کو اپ ڈیٹ کرنا |
| viewDidAppear | view کے اسکرین پر ظاہر ہونے کے بعد | اینیمیشنز شروع کرنا، اینیمیشن کا آغاز |
| viewWillDisappear | view کے غائب ہونے سے پہلے | داخل کردہ ڈیٹا محفوظ کرنا، کارروائیاں منسوخ کرنا |
| viewDidDisappear | view کے غائب ہونے کے بعد | وسائل کی آزادی، نوٹیفیکیشنز سے ان سبسکرائب ہونا |
| deinit | آبجیکٹ کے خاتمے پر | حتمی صفائی، مضبوط حوالہ جات کو جاری کرنا |
ان میں سے ہر طریقہ متعلقہ ٹرانزیشن کے لیے صرف ایک بار کال ہوتا ہے۔ استثنا — viewDidLoad، جو دوبارہ کال ہو سکتا ہے اگر ViewController وسائل کی کمی کی وجہ سے میموری سے ان لوڈ ہو گیا ہو اور پھر بحال کیا گیا ہو۔ اس صورت میں، viewDidDisappear دوبارہ viewDidLoad سے پہلے آئے گا۔
طریقہ کی سگنیچر میں animated پیرامیٹر بتاتا ہے کہ آیا ٹرانزیشن اینیمیٹڈ تھی۔ یہ بغیر اینیمیشن کے پروگرامیٹک ٹرانزیشنز (مثال کے طور پر، rootViewController سیٹ کرتے وقت) اور صارف کے ذریعے شروع کردہ اینیمیٹڈ ٹرانزیشنز میں فرق کرنے کے لیے مفید ہے۔ اگر ویلیو false ہے تو ممکن ہے کہ کنٹرولر کو سسٹم نے زبردستی چھپایا ہو — اس صورت میں، وقت پر منحصر کچھ کارروائیاں غیر متعلق ہو سکتی ہیں۔
سسٹم viewDidDisappear کو صرف دو منظرناموں میں کال کرتا ہے: جب ViewController نیویگیشن اسٹیک سے ہٹا دیا جاتا ہے اور جب اسے کسی دوسرے کنٹرولر سے ڈھانپ دیا جاتا ہے۔ دونوں صورتوں میں، طریقہ اشارہ کرتا ہے کہ view صارف کو مزید نظر نہیں آ رہی ہے، اور ڈیولپر کو وہ وسائل خالی کرنے چاہئیں جو بیک گراؤنڈ میں ضروری نہیں ہیں۔ ان منظرناموں کو سمجھنا ایپلی کیشن کی حالت کے بارے میں غلط مفروضوں کو روکتا ہے۔
پہلا منظر — UINavigationController سے pop۔ جب صارف «پیچھے» کے بٹن پر کلک کرتا ہے، popViewController: animated کال ہوتا ہے۔ موجودہ کنٹرولر viewDidDisappear وصول کرتا ہے، اور پھر، اگر اس پر مزید مضبوط حوالہ جات نہیں ہیں، deinit کال ہوتا ہے۔ دوسرا منظر — present/dismiss۔ جب موڈل طور پر نیا کنٹرولر دکھایا جاتا ہے، presentingViewController viewDidDisappear وصول کرتا ہے۔ dismiss پر یہ طریقہ اس کنٹرولر پر کال ہوتا ہے جو موڈل طور پر دکھایا گیا تھا۔
تیسرا، کم واضح منظر — child ViewController کا اضافہ۔ اگر کنٹینر کنٹرولر (مثال کے طور پر، UIPageViewController یا UITabBarController) میں نیا child کنٹرولر شامل کیا جاتا ہے، تو فعال child کنٹرولر viewDidDisappear وصول کرتا ہے۔ یہ ٹیبز یا پیج کیروسل والی ایپلی کیشنز کے لیے اہم ہے — ہر tab تبدیلی کو غیر فعال اسکرین کے کام کو درست طریقے سے روکنا چاہیے۔
ایک اہم استثنا موجود ہے: اگر UIViewController موڈل ونڈو میں دکھایا جا رہا ہے اور صرف اسے نیچے سکرول کر کے انٹرایکٹیو طریقے سے بند کرتا ہے، تو سسٹم نامکمل سکرول پر viewDidDisappear کال نہیں کر سکتا۔ یہ رویہ iOS 13 میں انٹرایکٹیو dismiss کے ساتھ سامنے آیا۔ ڈیولپرز کو چاہیے کہ وہ واقعہ کی ضمانت شدہ وصولی کے لیے UIAdaptivePresentationControllerDelegate اور didDismiss طریقہ کے ذریعے حالت کو ہینڈل کریں۔
ایک اور خصوصیت — میموری وارننگز۔ میموری کی کمی پر سسٹم اس کنٹرولر کے view کو ان لوڈ کر سکتا ہے جو اسکرین پر ظاہر نہیں ہو رہا ہے۔ اس صورت میں viewDidDisappear عام طور پر ان لوڈنگ سے پہلے کال ہوتا ہے، لیکن ڈیولپر کو حفاظتی اقدام کے طور پر اہم وسائل کی آزادی کی کارروائیوں کو didReceiveMemoryWarning میں بھی ڈپلیکیٹ کرنا چاہیے۔ یہ طریقہ انتہائی حالات میں ڈیٹا کے نقصان کو روکتا ہے۔
viewDidDisappear تین اہم اقسام کی کارروائیوں کے لیے استعمال ہوتا ہے: سرگرمیاں روکنا، وسائل خالی کرنا اور حالت محفوظ کرنا۔ ہر قسم کے اپنے بہترین طریقے ہیں جو iOS ڈیولپرز کی کمیونٹی نے تیار کیے ہیں۔ آئیے نفاذ کی مثالوں کے ساتھ سب سے عام منظرناموں پر غور کرتے ہیں۔
عام غلطی — viewDidLoad میں نوٹیفیکیشنز پر سبسکرائب ہونا اور کبھی ان سبسکرائب نہ ہونا۔ یہ تباہ شدہ آبجیکٹ پر ہینڈلر کے کال ہونے کا باعث بنتا ہے، جو کریش کا سبب بنتا ہے۔ درست طریقہ — viewWillAppear میں سبسکرائب ہونا اور viewDidDisappear میں ان سبسکرائب ہونا، جو اس بات کی ضمانت دیتا ہے کہ سبسکرپشن صرف اس وقت فعال ہے جب کنٹرولر اسکرین پر ظاہر ہو رہا ہو۔
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(
self,
selector: #selector(handleKeyboardShow),
name: UIResponder.keyboardWillShowNotification,
object: nil
)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
یہ پیٹرن اس بات کی ضمانت دیتا ہے کہ نوٹیفیکیشن ہینڈلر صرف اس وقت فعال ہے جب کنٹرولر اسکرین پر نظر آ رہا ہے۔ دوسری سکرین پر جاتے وقت تمام سبسکرپشنز خود بخود ہٹا دی جاتی ہیں، اور واپسی پر بحال ہو جاتی ہیں۔ یہ ایپلی کیشن کی اعتمادیت کو بڑھاتا ہے اور نوٹیفیکیشنز سے متعلق بگز کے طبقے کو ختم کرتا ہے۔
آئیے اصلی پروجیکٹس میں viewDidDisappear کے استعمال کی دو عملی مثالوں پر غور کرتے ہیں۔ پہلی مثال سکرین چھپنے پر ٹائمر روکنے کو ظاہر کرتی ہے، دوسری — کی بورڈ کے مشاہدے کو درست طریقے سے ختم کرنا۔ دونوں مثالیں کنٹرولر کے غیر فعال ہونے پر وسائل کی آزادی کے اصول پر عمل کرتی ہیں۔
اگر سکرین پر UI کو اپ ڈیٹ کرنے کے لیے Timer کام کر رہا ہے (مثال کے طور پر، الٹی گنتی یا کیروسل)، تو اسے کنٹرولر کے چھپنے پر روکنا ضروری ہے۔ بیک گراؤنڈ میں ٹائمر کا چلتا رہنا نہ صرف پروسیسر کے وسائل استعمال کرتا ہے بلکہ پوشیدہ UI کو اپ ڈیٹ کرنے کی کوشش پر استثنا کا باعث بھی بن سکتا ہے۔
class CountdownViewController: UIViewController {
private var countdownTimer: Timer?
private var remainingSeconds: Int = 60
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
startTimer()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
invalidateTimer()
}
private func invalidateTimer() {
countdownTimer()?.invalidate()
countdownTimer = nil
}
}
بہت سی ایپلی کیشنز میں AVPlayer بلٹ ان پلیئر میں ویڈیو چلاتا ہے۔ اگر صارف دوسری سکرین پر جاتا ہے تو ویڈیو خود بخود رک جانا چاہیے۔ viewDidDisappear میں نفاذ اس بات کی ضمانت دیتا ہے کہ سکرین کے مکمل چھپنے کے بعد روک ہوتی ہے — یہ ٹرانزیشن پر بلیک فریم کے جھلملاہٹ کو روکتا ہے۔
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if player().timeControlStatus == .playing {
player().pause()
playerLayer().removeFromSuperlayer()
}
player = nil
}
روکنے کے بعد متغیر player کو صفر کرنا ویڈیو بفرز کے زیر قبضہ میموری کو اضافی طور پر خالی کرتا ہے۔ یہ طریقہ خاص طور پر لمبی ویڈیوز والی ایپلی کیشنز کے لیے اہم ہے، جہاں بفر درجنوں میگا بائٹس پر قبضہ کر سکتا ہے۔ روکنے کو حوالہ جات صفر کرنے کے ساتھ ملانا بیک گراؤنڈ میں ایپلی کیشن کے فٹ پرنٹ کو کم سے کم کرتا ہے۔
viewDidDisappear کو اکثر viewWillDisappear اور deinit کے ساتھ الجھایا جاتا ہے، تاہم ان میں سے ہر طریقے کی اپنی ذمہ داری کا دائرہ ہے۔ ان کے درمیان حدود کو سمجھنا iOS ایپلی کیشن کے مستحکم آرکیٹیکچر کی کنجی ہے۔ غلط استعمال وسائل کی دوہری آزادی یا اس کے برعکس ان کے لیک ہونے کا باعث بن سکتا ہے۔
viewDidDisappear اور viewWillDisappear کے درمیان بنیادی فرق — کال ہونے کا لمحہ۔ viewWillDisappear اس وقت کال ہوتا ہے جب view ابھی نظر آ رہی ہے لیکن غائب ہونے کی تیاری کر رہی ہے۔ یہ نظر آنے والے ڈیٹا (ان پٹ فیلڈز میں متن) کو محفوظ کرنے کے لیے موزوں ہے۔ viewDidDisappear اینیمیشن مکمل ہونے کے بعد کال ہوتا ہے، جب view یقینی طور پر نظر نہیں آ رہی — بصری حالت سے غیر متعلق وسائل کی آزادی کے لیے مثالی۔
deinit، viewDidDisappear کے برعکس، صرف اس وقت کال ہوتا ہے جب UIViewController آبجیکٹ میموری میں ختم ہوتا ہے۔ اگر کنٹرولر صرف چھپا ہوا ہے (مثال کے طور پر، موڈل ونڈو سے ڈھانپا گیا ہے) تو deinit کال نہیں ہوتا۔ اس صورت میں viewDidDisappear اختتامی کارروائیاں انجام دینے کا واحد مقام ہے۔ وسائل کی مکمل آزادی deinit میں ہونی چاہیے، لیکن viewDidDisappear دوبارہ ظاہر ہونے تک عارضی آزادی کے لیے ذمہ دار ہے۔
SwiftUI استعمال کرتے ہوئے ترقی میں viewDidDisappear طریقہ استعمال نہیں ہوتا — اس کی جگہ .onDisappear موڈیفائر لیتا ہے، جو اسی طرح کام کرتا ہے۔ تاہم SwiftUI میں لائف سائیکل پر براہ راست کنٹرول نہیں ہے، اور ڈیولپرز وسائل کے انتظام کے لیے Combine اور State-آبجیکٹس پر انحصار کرتے ہیں۔ UIKit ایپلی کیشنز کے لیے viewDidDisappear سکرین چھپنے کے انتظام کا بنیادی ذریعہ ہے۔
تجربہ کار iOS ڈیولپرز بھی viewDidDisappear کے ساتھ کام کرتے ہوئے غلطیاں کرتے ہیں۔ آئیے پانچ سب سے عام مسائل اور ان سے بچنے کے طریقوں پر غور کرتے ہیں۔ ان anti-patterns کا علم کنٹرولرز کے لائف سائیکل سے متعلق مشکل سے پکڑے جانے والے بگز سے بچنے میں مدد کرے گا۔
خاص توجہ تھریڈ سیفٹی کی مستحق ہے۔ اگر viewDidDisappear مین تھریڈ پر کال ہوتا ہے (جو UIKit یقینی بناتا ہے)، لیکن وسائل کی آزادی میں اسینکرونس کارروائیاں شامل ہیں، تو مشترکہ ڈیٹا تک رسائی کو سنکرونائز کرنا ضروری ہے۔ اسینکرونس کام مکمل ہونے کے بعد UI کو اپ ڈیٹ کرنے کے لیے viewDidDisappear کے اندر DispatchQueue.main.async کا استعمال ایک عام لیکن درست طریقہ ہے۔
ایک اور اہم anti-pattern — viewDidDisappear کے اندر ڈیلیگیٹ طریقوں کو کال کرنا جو نئی ٹرانزیشن یا موڈل ڈسپلے شروع کر سکتے ہیں۔ یہ ایک ایسا چکر بناتا ہے جس میں viewDidDisappear پہلے کال کے مکمل ہونے سے پہلے دوبارہ کال ہو سکتا ہے۔ Apple لائف سائیکل کے طریقوں کے اندر موڈل ڈسپلے سے گریز کرنے کی سفارش کرتا ہے، انہیں علیحدہ ایونٹ ہینڈلرز میں رکھیں۔
اکثر پوچھے جانے والے سوالات
viewWillDisappear چھپنے کی اینیمیشن شروع ہونے سے پہلے کال ہوتا ہے، جب view ابھی نظر آ رہی ہے۔ viewDidDisappear — view کے مکمل غائب ہونے کے بعد۔ ڈیٹا محفوظ کرنے کے لیے viewWillDisappear استعمال کریں، وسائل کی آزادی کے لیے — viewDidDisappear۔
ہاں، super.viewDidDisappear(animated) کا کال لازمی ہے۔ UIKit اس طریقہ کو اندرونی نوٹیفیکیشنز اور ٹرانزیشن کی حالت مکمل کرنے کے لیے استعمال کرتا ہے۔ super کال کے بغیر UINavigationController اور UITabBarController میں خرابی ممکن ہے۔
ہاں، iOS 13+ میں انٹرایکٹیو dismiss (نیچے سکرول) پر اگر جیسچر مکمل نہ ہو تو طریقہ کال نہیں ہو سکتا۔ واقعہ کی ضمانت شدہ وصولی کے لیے UIAdaptivePresentationControllerDelegate ڈیلیگیٹ اور presentationControllerDidDismiss طریقہ استعمال کریں۔
deinit صرف آبجیکٹ کے خاتمے پر کال ہوتا ہے، جبکہ viewDidDisappear ہر چھپنے پر کال ہوتا ہے۔ ہر ٹرانزیشن پر وسائل کی آزادی کے لیے (مثال کے طور پر، نوٹیفیکیشنز سے ان سبسکرائب ہونا) viewDidDisappear استعمال کریں۔ کنٹرولر ہٹائے جانے پر حتمی صفائی کے لیے — deinit۔
SwiftUI میں viewDidDisappear کی جگہ .onDisappear { } موڈیفائر استعمال ہوتا ہے۔ یہ view کے درجہ بندی سے چھپنے پر کال ہوتا ہے۔ UIKit کے برعکس، SwiftUI اینیمیشنز کے دوران تمام منظرناموں میں onDisappear کے کال ہونے کی ضمانت نہیں دیتا۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں