viewWillDisappear হল UIViewController এর একটি পদ্ধতি যা UIKit ডাকে ঠিক তার আগে যে স্ক্রিনটি ব্যবহারকারীর ডিসপ্লে থেকে অদৃশ্য হতে শুরু করে। Apple Developer Documentation অনুযায়ী, এই পদ্ধতিটি animated প্যারামিটার গ্রহণ করে এবং push, pop, present, dismiss এবং ট্যাব পরিবর্তনে ট্রিগার হয়। viewWillDisappear অবস্থা সংরক্ষণ এবং সঠিকভাবে সম্পদ পরিষ্কারের জন্য প্রধান জায়গা।
মূখ্য বিষয়সমূহ
viewWillDisappear হল UIViewController এর একটি পদ্ধতি যা UIKit ডাকে ঠিক তার আগে যে নিয়ন্ত্রকের ভিউ স্ক্রিন থেকে অদৃশ্য হতে শুরু করে। এই মুহূর্তে স্ক্রিনটি ব্যবহারকারীর কাছে এখনও দৃশ্যমান, কিন্তু রূপান্তর ইতিমধ্যেই শুরু হয়েছে: NavigationController push/pop এনিমেশন শুরু করেছে, মোডাল ভিউ বন্ধ হতে শুরু করেছে, অথবা TabBar অন্য ট্যাবে স্যুইচ করা শুরু করেছে। ডিভেলপার সেই কাজগুলি করার জন্য এই পদ্ধতিটি ওভারাইড করে যার জন্য স্ক্রিনটি এখনও প্রবেশযোগ্য হতে হবে কিন্তু লুকিয়ে ফেলার জন্য প্রস্তুত হচ্ছে।
viewDidDisappear এর বিপরীতে, যা স্ক্রিন লুকোনোর পরে ট্রিগার হয়, viewWillDisappear ডেটা সংরক্ষণ এবং সম্পদ মুক্ত করার শেষ সুযোগ প্রদান করে যতক্ষণ ব্যবহারকারী ইন্টারফেস দেখতে পারে। এটি UX এর জন্য অত্যন্ত গুরুত্বপূর্ণ — একটি ড্রাফ্ট সংরক্ষণ বা টাইমার বন্ধ করা অবশ্যই ব্যবহারকারী অন্য স্ক্রিনে স্যুইচ করার আগে হতে হবে।
পদ্ধতিটি animated প্যারামিটার গ্রহণ করে, যা ইংদিকেট করে যে অদৃশ্যতা এনিমেটেড কিনা। true এর অর্থ হল UIKit একটি এনিমেটেড রূপান্তর করছে, false এর অর্থ হল স্ক্রিনটি তাত্ক্ষণিক অদৃশ্য হয়, উদাহরণস্বরূপ এনিমেশন ছাড়া dismiss অথবা প্রোগ্রামেটিকভাবে হাইয়ারার্কি থেকে সরানোর সময়।
viewWillDisappear সেই সব পরিদৃশ্যে ডাকা হয় যেখানে বর্তমান স্ক্রিনটি সক্রিয় হতে থামে। iOS ডিভেলপমেন্টের জন্য নির্দিষ্ট প্রধান কেসগুলি পর্যালোচনা করি।
যখন UINavigationController একটি নতুন নিয়ন্ত্রকের push করে, তখন রূপান্তর এনিমেশনের শুরুতে বর্তমানটিতে viewWillDisappear ডাকা হয়। এই মুহূর্তে বর্তমান স্ক্রিনটি এর উপর স্লাইড করা নতুন নিয়ন্ত্রকের নিচে এখনও দৃশ্যমান। এটি হল মানক পরিদৃশ্য যেখানে viewWillDisappear animated = true সহ ট্রিগার হয়।
যখন ব্যবহারকারী ব্যাক বটন টিপে অথবা ইন্টার্যাক্টিভ স্যাইপ ব্যাক করে, তখন বর্তমান নিয়ন্ত্রকে viewWillDisappear ডাকা হয়। ইন্টার্যাক্টিভ অঙ্গিক ভঙ্গিমায় এই কলটি বাতিল হতে পারে যদি ব্যবহারকারী তার মন পরিবর্তন করে এবং স্ক্রিনটিকে এর জায়গায় ফিরিয়ে আনে। অবস্থা সংরক্ষণ ডিজাইন করার সময় এটি একটি গুরুত্বপূর্ণ বৈশিষ্ট্য যা মনে রাখা উচিত।
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
saveDraftData()
NotificationCenter.default.removeObserver(self)
}
একটি মোডাল ভিউ বন্ধ করার সময়, dismiss এনিমেশনের শুরুতে বন্ধ হচ্ছে যা নিয়ন্ত্রকে viewWillDisappear ডাকা হয়। এই বিন্দুতে আপনি ডিলিগেট অথবা ক্লোজারের মাধ্যমে ফলাফল পঠাতে পারেন, কারণ যে নিয়ন্ত্রকটি মোডালটি উপস্থাপন করেছিল সে এখনও নিয়ন্ত্রণ ফিরে পায়নি।
UITabBarController ব্যবহারকারী অন্য ট্যাব স্পর্শ করার পরেই পরিত্যক্ত ট্যাবের নিয়ন্ত্রকে viewWillDisappear ডাকে। যদি বর্তমান ট্যাবে সক্রিয় প্রক্রিয়া থাকে — মিডিয়া প্লেব্যাক, ফাইল ডাউনলোড, টাইমার — তবে সেগুলি এখানে বন্ধ অথবা বিরত করা উচিত।
viewWillDisappear সম্পদ এবং অবস্থা ব্যবস্থাপনা সম্পর্কিত নির্দিষ্ট কাজ সমাধান করে। কোড উদাহরণ সহ মূল পরিদৃশ্যগুলি পর্যালোচনা করি।
viewWillDisappear এর সবচেয়ে গুরুত্বপূর্ণ কাজ হল বর্তমান স্ক্রিনে ব্যবহারকারী যে ডেটা প্রবেশ অথবা পরিবর্তন করেছে তা সংরক্ষণ করা। বার্তা ড্রাফ্ট, সম্পাদিত ফর্ম ফিল্ড, নির্বাচিত সেটিংস — এসব সব স্ক্রিন অদৃশ্য হোওয়ার আগে সংরক্ষণ করা উচিত। পার্সিস্টেন্সের জন্য Core Data, UserDefaults অথবা ফাইল স্টোরেজ ব্যবহার করুন।
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
guard hasUnsavedChanges else { return }
draftStorage.save(currentDraft)
}
NotificationCenter, KVO এবং Combine পাবলিশার যাতে আপনি viewWillAppear অথবা viewDidLoad এ সাবস্ক্রাইব করেছিলেন সেগুলি viewWillDisappear এ বাতিল করা উচিত। এটি না কলে, বিজ্ঞপ্তিগুলি লুকানো স্ক্রিনে আসবে, যা ব্যবহারকারী দেখতে পাবে না এমন UI আপডেট হবে, অথবা — আরও খারাপ — ইতিমধ্যে ডিআলোকেট করা অবজেক্টে প্রবেশ করার কারণে ক্র্যাশ হবে।
viewDidAppear এ শুরু করা UIView এনিমেশন এবং Timer অথবা DispatchSource এর মাধ্যমে চলমান টাইমারগুলি viewWillDisappear এ বন্ধ করা উচিত। লুকানো স্ক্রিনে জারীয় এনিমেশন ব্যবহারকারীর জন্য কোনো লাভ ছাড়াই GPU এবং ব্যাটারি নষ্ট করে। টাইমারে invalidate এবং লেয়ারে removeAllAnimations ডাকার মাধ্যমে স্পষ্টভাবে সেগুলি বন্ধ করুন।
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
countdownTimer?.invalidate()
countdownTimer = nil
loadingIndicator.layer.removeAllAnimations()
}
যদি কোন নিয়ন্ত্রক ফলাফল পেতে খোলা হয়েছিল — একটি আইটম নির্বাচন, টেক্সট প্রবেশ, কাজ নিশ্চিতকরণ — viewWillDisappear হল শেষ মুহূর্ত যখন মূল নিয়ন্ত্রকটি স্ট্যাকে এখনও বিদ্যমান এবং ডেটা গ্রহণ করতে পারে। deinit কল হোওয়ার আগে ডিলিগেট অথবা ক্লোজার কল করুন।
বিশ্বস্ত অবস্থা সংরক্ষণ iOS ডিভেলপমেন্টের একটি সবচেয়ে কঠিন কাজ। viewWillDisappear কৌশলের একটি গুরুত্বপূর্ণ কিন্তু একমাত্র উপাদান নয়। একটি ব্যাপক পদ্ধতি দেখি।
স্তর 1 — viewWillDisappear এ সংরক্ষণ। হালকা ডেটার দ্রুত সংরক্ষণ যা ফিরে আসার পরেই পাওয়া উচিত। UI অবস্থার জন্য উপযুক্ত: স্ক্রল অবস্থান, নির্বাচিত সেগমেন্ট, ইনপুট ফিল্ডে টেক্সট। সমস্যা: বাতিল ইন্টার্যাক্টিভ pop অঙ্গিক ভঙ্গিমায়, সংরক্ষণ হয় যদিও ব্যবহারকারী স্ক্রিনে রয়েছে — ডেটা অনাবশ্যকভাবে অযর্ওভাবে লেখা হয়।
স্তর 2 — viewDidDisappear এ সংরক্ষণ। প্রথম স্তরের সংরক্ষণ ডপ্লিকেট করে কিন্তু শুধুমাত্র স্ক্রিনটি গারংটিভাবে লুকানো হলেই ট্রিগার হয়। এটি বাতিল অঙ্গিক ভঙ্গিমায় হতে একটি সুরক্ষা। যাকি, আপনি ইতিমধ্যেই viewWillDisappear এ বিজ্ঞপ্তি থেকে আনসাবস্ক্রাইব করে থাকলে, viewDidDisappear এর কিছু ডেটায় প্রবেশ নাও থাকতে পারে।
স্তর 3 — অ্যাপলিকেশন বিজ্ঞপ্তির মাধ্যমে সংরক্ষণ। UIApplication.willResignActiveNotification এবং UIApplication.didEnterBackgroundNotification অ্যাপ ব্যাকগ্রাংড হোওয়া ধরে। যদি ব্যবহারকারী অ্যাপটি ছোট করে, তবে viewWillDisappear কল নাও হতে পারে — কিন্তু এই বিজ্ঞপ্তির মাধ্যমে সংরক্ষণ গারংটি দেয় যে সত্রের শেষে ডেটা অখংড় থাকবে।
| স্তর | পদ্ধতি/বিজ্ঞপ্তি | বিশ্বসনীয়তা | ব্যবহার |
|---|---|---|---|
| 1 | viewWillDisappear | উচ্চ | UI অবস্থা, ড্রাফ্ট |
| 2 | viewDidDisappear | অত্যন্ত উচ্চ | গুরুত্বপূর্ণ ডেটা |
| 3 | willResignActive | সর্বোচ্চ | অ্যাপ ব্যাকগ্রাংড হলে |
সুপারিশ: গুরুত্বপূর্ণ ব্যবহারকারী ডেটার জন্য তিনটি স্তরের সম্মিলন ব্যবহার করুন। অগুরুত্বপূর্ণ অবস্থার জন্য প্রথম স্তর যথেষ্ট। একই ডেটা একাধিকবার সংরক্ষণ না করা গুরুত্বপূর্ণ — একটি dirty ফ্ল্যাগ ব্যবহার করুন যা ইংদিকেট করে যে শেষ সংরক্ষণের পর ডেটা পরিবর্তিত হয়েছে।
CRUD স্ক্রিনের জন্য বিশেষ ধ্যান দেওয়া উচিত যেখানে ব্যবহারকারী ডেটা প্রবেশ করে। এমন স্ক্রিনে viewWillDisappear এ প্রতিটি কীস্ট্রোক সংরক্ষণ করা সুপারিশিত নয় — এটি অতিরিক্ত। Timer এর মাধ্যমে বিলম্ব (debounce) সহ অটো-সেভ ব্যবহার করুন, এবং viewWillDisappear শুধুমাত্র সেস জরুরি সংরক্ষণের জন্য ব্যবহার করুন যদি অসংরক্ষিত পরিবর্তন থাকে। এই পদ্ধতি কর্মদক্ষতা এবং ডেটা অখংড়তার মধ্যে সামঞ্জস্য সৃষ্টি করে।
Core Data ব্যবহারকারী অ্যাপের জন্য, একটি অতিরিক্ত পদক্ষেপ হল viewWillDisappear এ saveContext কল করা কেবলমাত্র যখন managed object context এ প্রকৃত পরিবর্তন থাকে। সংরক্ষণের আগে context.hasChanges যাচাই করা persistent store এ অনাবশ্যক লেখা রোধ করে এবং ডিভাইসের ব্যাটারি আয়ু বাড়ায়। এই যাচাইটিকে applicationDidEnterBackground এ গ্লোবাল সেভিংয়ের সাথে সম্মিলিত করুন।
ভুল ব্যবহার viewWillDisappear এর কারণে ডেটা হারানি, মেমোরি লিক এবং অস্থির অ্যাপ ব্যবহার হতে পারে। ঘন প্রাণ্ত iOS ডিভেলপার ভুলগুলি পর্যালোচনা করি।
প্রথম ভুল — শুধুমাত্র viewWillDisappear এ ডেটা সংরক্ষণ। যথা আলোচিত, ইন্টার্যাক্টিভ pop অঙ্গিক ভঙ্গিমায় পদ্ধতিটি ডাকা হয় যদিও স্ক্রিনটি অদৃশ্য হয়নি। যদি সংরক্ষণের পার্শ্ব প্রতিক্রিয়া থাকে — সার্ভারে ডেটা পাঠানো, অবস্থা পরিবর্তন — এটি মিথ্যা ট্রিগার সৃষ্টি করতে পারে। isBeingDismissed অথবা isMovingFromParent যাচাই যোগ করুন।
দ্বিতীয় ভুল — NotificationCenter থেকে আনসাবস্ক্রাইব না করা। iOS এ এটি একটি সবচেয়ে সাধারণ মেমোরি লিক। যদি আপনি viewWillAppear এ UIResponder.keyboardWillShowNotification এ সাবস্ক্রাইব করেন কিন্তু viewWillDisappear এ আনসাবস্ক্রাইব না করেন, ক্লোজারটি কল হতে থাকবে। নিয়ন্ত্রকের deinit এ, ক্লোজারটি একটি ডিআলোকেট অবজেক্টে রিফারেন্স করবে — অ্যাপ ক্র্যাশ নিশ্চিত।
তৃতীয় ভুল — ভারী সিঙ্ক্রোনাস কাজ করা। viewWillDisappear এ বৃহৎ পরিমাণে ডেটা সংরক্ষণ, Core Data অথবা ফাইল সিস্টেমে লেখা প্রধান থ্রেড ব্লক করে। যদি কাজটি রূপান্তর এনিমেশনের চেয়ে বেশি সময় নেয়, UIKit থ্রেডটি বিরত করে এবং ইন্টারফেস জমে যায়। ভারী সংরক্ষণ ব্যাকগ্রাংড ক্যুতে সরানোর জন্য ব্যবহার করুন।
চতুর্থ ভুল — super কল করতে ভুলে যাওয়া। super.viewWillDisappear না ডাকলে UINavigationController এবং UITabBarController ভেঙ্গে যেতে পারে, যারা তাদের অভ্যন্তরীণ অবস্থার জন্য এই পদ্ধতি ব্যবহার করে। Apple ডকুমেন্টেশন অনুসরণ করে super কে সবশেষে অথবা প্রথমে কল করুন।
এই সমস্যাটি iOS এ সক্রিয় মাল্টিটাস্কিং এবং অ্যাপ স্যুইচিংয়ের সাথে আরও খারাপ হয়। পঞ্চম ভুল — viewWillDisappear এ সংরক্ষণের পর DispatchQueue.main.async ব্যবহার করা। যদি আপনি super.viewWillDisappear কল করার পর প্রধান ক্যুতে একটি ব্লক অসিঙ্ক্রোনাসভাবে পাঠান, কোনো গারংটি নেই যে ব্লকটি করার সময় নিয়ন্ত্রকটি এখনও বিদ্যমান থাকবে। ডিআলোকেট মেমোরিতে প্রবেশ এবং অ্যাপ ক্র্যাশ রোধ করতে ক্লোজারের ভিতরে সবশময় দুর্বল রিফারেন্স [weak self] ব্যবহার করুন।
বারংবার জিজ্ঞাসিত প্রশ্ন
viewWillDisappear অদৃশ্যতার শুরুতে ডাকা হয় যখন স্ক্রিনটি এখনও দৃশ্যমান। viewDidDisappear স্ক্রিন সম্পূর্ণরূপে লুকানো এবং এনিমেশন শেষ হোওয়ার পর ডাকা হয়।
সংরক্ষণ নিশ্চিত করতে viewDidDisappear ব্যবহার করুন অথবা viewWillDisappear এর ভিতরে isMovingFromParent এবং isBeingDismissed বৈশিষ্ট্য যাচাই করুন যে স্ক্রিনটি প্রকৃতে অদৃশ্য হবে কিনা।
হ্যাঁ, অবশ্যই যদি আপনি self এর সাথে ব্লক অথবা সেলেক্টর ব্যবহার করেন। ARC NotificationCenter সাবস্ক্রিপশন পরিচালনা করে না। iOS 9+ এ ব্লকের জন্য একটি দুর্বল রিফারেন্স ব্যবহার করুন এবং viewWillDisappear এ আনসাবস্ক্রাইব করুন।
কোনো উপায় নেই — force quit জীবনচক্রের পদ্ধতিগুলিকে ডাকে না। অ্যাপ সমাপ্তিতে গারংটিভাবে সংরক্ষণের জন্য UIApplication.willTerminateNotification ব্যবহার করুন অথবা ডেটা পরিবর্তনের সাথে সাথে রিয়াল টাইমে সংরক্ষণ করুন।
হ্যাঁ, ইন্টার্যাক্টিভ পপ অঙ্গিক ভঙ্গিমায় UIKit অঙ্গিক ভঙ্গিমা শুরু হোওয়ার পরেই viewWillDisappear ডাকে। যদি ব্যবহারকারী অঙ্গিক ভঙ্গিমা বাতিল করে, স্ক্রিনটি দৃশ্যমান থাকে কিন্তু পদ্ধতিটি ইতিমধ্যেই চলে গেছে। সবশময় isMovingFromParent যাচাই করুন।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন