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, หน้าต่างโมดอลเริ่มปิด หรือ TabBar เริ่มเปลี่ยนไปยังแท็บอื่น นักพัฒนาจะโอเวอร์ไรด์เมธอดนี้เพื่อดำเนินการที่จำเป็นต้องให้หน้าจอยังเข้าถึงได้ แต่กำลังเตรียมที่จะถูกซ่อน

แตกต่างจาก viewDidDisappear ที่ทำงานหลังจากที่หน้าจอถูกซ่อนแล้ว viewWillDisappear ให้ โอกาสสุดท้าย ในการบันทึกข้อมูลและปล่อยทรัพยากรในขณะที่ผู้ใช้ยังเห็นอินเทอร์เฟซอยู่ นี่เป็นสิ่งสำคัญอย่างยิ่งสำหรับ UX — การบันทึกร่างหรือหยุดตัวจับเวลาควรเกิดขึ้นก่อนที่ผู้ใช้จะเปลี่ยนไปยังหน้าจออื่น

เมธอดรับพารามิเตอร์ animated ซึ่งระบุว่าการหายไปเกิดขึ้นพร้อมแอนิเมชันหรือไม่ ค่า true หมายถึง UIKit ดำเนินการเปลี่ยนผ่านด้วยแอนิเมชัน ส่วน false หมายถึงหน้าจอหายไปทันที เช่นเมื่อ dismiss โดยไม่มีแอนิเมชันหรือการลบออกจากลำดับชั้นโดยทางโปรแกรม

เมื่อใด viewWillDisappear ถูกเรียก

viewWillDisappear ถูกเรียกในทุกสถานการณ์ที่หน้าจอปัจจุบันหยุดเป็นหน้าจอที่ใช้งาน เรามาดูกรณีหลักที่เฉพาะเจาะจงกับการพัฒนา iOS

เมื่อ push หน้าจอใหม่

เมื่อ UINavigationController ทำการ push คอนโทรลเลอร์ใหม่ viewWillDisappear ของคอนโทรลเลอร์ปัจจุบันจะถูกเรียกที่จุดเริ่มต้นของแอนิเมชันการเปลี่ยนผ่าน ในขณะนี้หน้าจอปัจจุบัน ยังคงมองเห็นได้ ใต้คอนโทรลเลอร์ใหม่ที่เลื่อนขึ้นมาด้านบน นี่เป็นสถานการณ์มาตรฐานที่ viewWillDisappear ทำงานด้วย animated = true

เมื่อ pop หน้าจอปัจจุบัน

เมื่อผู้ใช้กดปุ่ม back หรือทำท่าทางปัดกลับแบบอินเทอร์แอคทีฟ viewWillDisappear ของคอนโทรลเลอร์ปัจจุบันจะถูกเรียก ในการปัดแบบอินเทอร์แอคทีฟ การเรียกนี้อาจ ถูกยกเลิก หากผู้ใช้เปลี่ยนใจและดึงหน้าจอกลับไปยังตำแหน่งเดิม นี่เป็นคุณสมบัติสำคัญที่ต้องพิจารณาเมื่อออกแบบการบันทึกสถานะ

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

เมื่อ dismiss คอนโทรลเลอร์

เมื่อปิดหน้าต่างโมดอล viewWillDisappear จะถูกเรียกบนคอนโทรลเลอร์ที่กำลังถูกปิดที่จุดเริ่มต้นของแอนิเมชัน dismiss ในขณะนี้สามารถส่งผลลัพธ์กลับผ่าน delegate หรือ closure เนื่องจากคอนโทรลเลอร์ที่แสดงหน้าต่างโมดอลยังไม่ได้รับการควบคุม

เมื่อเปลี่ยนแท็บ 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 publishers ที่คุณสมัครรับใน viewWillAppear หรือ viewDidLoad ควรถูกยกเลิกใน viewWillDisappear หากไม่ทำเช่นนั้น การแจ้งเตือนจะยังคงมาถึงหน้าจอที่ถูกซ่อน ทำให้เกิดการอัปเดต UI ที่ผู้ใช้ไม่เห็น หรือที่แย่กว่านั้น — เกิดการขัดข้องจากการเข้าถึงออบเจกต์ที่ถูกปล่อยไปแล้ว

การหยุดแอนิเมชันและตัวจับเวลา

แอนิเมชัน 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สูงสุดเมื่อย่อขนาด

คำแนะนำ: ใช้การผสมผสานทั้งสามระดับสำหรับข้อมูลผู้ใช้ที่สำคัญ สำหรับสถานะที่ไม่สำคัญ — ใช้แค่ระดับแรกก็เพียงพอ สิ่งสำคัญคือไม่บันทึกข้อมูลเดียวกันซ้ำหลายครั้ง — ใช้แฟล็ก dirty ที่ระบุว่าข้อมูลเปลี่ยนแปลงไปตั้งแต่การบันทึกครั้งล่าสุด

ควรให้ความสนใจเป็นพิเศษกับกลยุทธ์สำหรับหน้าจอ CRUD ที่ผู้ใช้ป้อนข้อมูล ในหน้าจอดังกล่าว ไม่แนะนำให้บันทึกทุกการกดแป้นพิมพ์ใน viewWillDisappear — ซึ่งมากเกินไป ใช้ auto-save แบบหน่วงเวลา (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 จะอ้างอิงถึงออบเจกต์ที่ถูกปล่อยไปแล้ว — การขัดข้องของแอปพลิเคชันจะเกิดขึ้นอย่างแน่นอน

ข้อผิดพลาดที่สาม — การดำเนินการซิงโครนัสที่หนักหน่วง การบันทึกข้อมูลปริมาณมาก การเขียนไปยัง Core Data หรือระบบไฟล์ใน viewWillDisappear จะบล็อก main thread หากการดำเนินการใช้เวลานานกว่าแอนิเมชันการเปลี่ยนผ่าน UIKit จะหยุดเธรดและอินเทอร์เฟซ ค้าง ย้ายการบันทึกที่หนักหน่วงไปยังคิวพื้นหลัง

ข้อผิดพลาดที่สี่ — ลืมเรียก super การไม่เรียก super.viewWillDisappear อาจทำให้การทำงานของ UINavigationController และ UITabBarController ผิดปกติ ซึ่งใช้เมธอดนี้สำหรับสถานะภายในของตน เรียก super ก่อนหรือหลังเสมอ ตามเอกสารประกอบของ Apple

ปัญหานี้รุนแรงขึ้นใน iOS ที่มีการทำงานหลายอย่างพร้อมกันและการสลับระหว่างแอปพลิเคชัน ข้อผิดพลาดที่ห้า — การใช้ DispatchQueue.main.async หลังจากบันทึกใน viewWillDisappear หากคุณส่งบล็อกแบบอะซิงโครนัสไปยังคิวหลักหลังจากเรียก super.viewWillDisappear ไม่มีการรับประกันว่าคอนโทรลเลอร์ยังคงมีอยู่ในขณะที่บล็อกทำงาน ใช้ weak references [weak self] ภายใน closures เสมอเพื่อป้องกันการเข้าถึงหน่วยความจำที่ถูกปล่อยไปแล้วและป้องกันการขัดข้องของแอปพลิเคชัน

คำถามที่พบบ่อย

viewWillDisappear แตกต่างจาก viewDidDisappear อย่างไร?

viewWillDisappear ถูกเรียกเมื่อเริ่มการหายไป ในขณะที่หน้าจอยังมองเห็นได้ ส่วน viewDidDisappear ถูกเรียกหลังจากที่หน้าจอถูกซ่อนอย่างสมบูรณ์และแอนิเมชันเสร็จสิ้น

จะทำอย่างไรเมื่อท่าทาง pop ถูกยกเลิก?

ใช้ viewDidDisappear เพื่อยืนยันการบันทึก หรือตรวจสอบคุณสมบัติ isMovingFromParent และ isBeingDismissed ภายใน viewWillDisappear เพื่อระบุว่าหน้าจอจะหายไปจริงหรือไม่

จำเป็นต้องยกเลิกการสมัครรับจาก NotificationCenter ด้วยตนเองหรือไม่?

ใช่ จำเป็นอย่างยิ่ง หากคุณใช้บล็อกหรือ selectors กับ self ARC ไม่จัดการการสมัครรับของ NotificationCenter ใน iOS 9+ สำหรับบล็อกให้ใช้ weak reference และยกเลิกการสมัครใน 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 สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม