viewWillAppear เป็นเมธอด UIViewController ที่ UIKit เรียกทุกครั้งก่อนที่หน้าจอจะปรากฏให้ผู้ใช้เห็น ตาม เอกสารประกอบสำหรับนักพัฒนา Apple เมธอดนี้รับพารามิเตอร์บูลีน animated ที่ระบุว่าการเปลี่ยนผ่านเกิดขึ้นพร้อมกับแอนิเมชันหรือไม่ viewWillAppear เป็นสถานที่หลักสำหรับการอัปเดตข้อมูลและซิงโครไนซ์สถานะของหน้าจอ
ประเด็นสำคัญ
viewWillAppear เป็นเมธอด UIViewController ที่ UIKit เรียกทันทีก่อนที่จะเพิ่ม View ไปยังลำดับชั้นหน้าต่าง ในขณะนี้ View มีขนาดสุดท้ายหลังจากการผ่าน Auto Layout แล้ว แต่ยังไม่ปรากฏแก่ผู้ใช้ — แอนิเมชันการเปลี่ยนผ่านยังไม่ได้เริ่มหรือกำลังดำเนินการ นักพัฒนาจะโอเวอร์ไรด์เมธอดนี้เพื่อดำเนินการที่ควรเกิดขึ้นก่อนการแสดงหน้าจอแต่ละครั้ง
แตกต่างจาก viewDidLoad ที่ทำงานเพียงครั้งเดียว viewWillAppear ถูกเรียก ทุกครั้ง ที่หน้าจอกำลังจะปรากฏ: เมื่อเปิดครั้งแรก เมื่อกลับจากคอนโทรลเลอร์ลูก หลังจากปิดหน้าต่างโมดอล และเมื่อสลับแท็บ TabBar สิ่งนี้ทำให้เป็นเมธอดสำคัญสำหรับการรักษาสถานะอินเทอร์เฟซให้เป็นปัจจุบัน
เมธอดรับพารามิเตอร์ animated ชนิด Bool ซึ่งเป็น true หากการปรากฏของหน้าจอมาพร้อมกับแอนิเมชัน พารามิเตอร์นี้สะดวกในการส่งต่อไปยังเมธอด NavigationBar และ TabBar ซึ่งมีพารามิเตอร์คล้ายกันสำหรับพฤติกรรมที่สอดคล้องกัน
ช่วงเวลา ของการเรียก viewWillAppear ขึ้นอยู่กับประเภทการนำทาง แต่กฎทั่วไปไม่เปลี่ยนแปลง: เมธอดจะทำงานก่อนที่ View จะปรากฏ มาดูสถานการณ์หลักกัน
หลังจาก viewDidLoad UIKit เริ่มเตรียมการแสดงผล: View ถูกเพิ่มไปยังลำดับชั้น, การผ่าน layout ถูกเรียกใช้, และทันทีก่อนที่แอนิเมชันการเปลี่ยนผ่านจะเริ่มขึ้น viewWillAppear จะถูกเรียก ในขณะนี้ หน้าจอ ยังไม่ปรากฏ แต่ซับวิวทั้งหมดมีขนาดที่ถูกต้อง และเนื้อหาของพวกเขาสามารถอัปเดตได้อย่างปลอดภัย
เมื่อผู้ใช้แตะปุ่มย้อนกลับหรือเรียก popViewController โดยโปรแกรม UIKit จะกลับไปยังหน้าจอก่อนหน้าและเรียก viewWillAppear ของมัน นี่คือ สถานการณ์หลัก สำหรับการใช้ viewWillAppear — อัปเดตรายการหลังจากเพิ่มรายการหรือซิงโครไนซ์การตั้งค่า
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
updateBadgeCount()
}
หลังจากปิดคอนโทรลเลอร์ที่แสดงแบบโมดอล UIKit จะเรียก viewWillAppear บนคอนโทรลเลอร์ที่แสดงมัน สถานการณ์นี้ ต้องการความสนใจเป็นพิเศษ หากคุณใช้ตัวแทนหรือคลosure เพื่อส่งข้อมูลกลับ — viewWillAppear รับประกันว่าหน้าจอจะอัปเดตหลังจากได้รับผลลัพธ์
TabBarController เรียก viewWillAppear บนคอนโทรลเลอร์ของแท็บที่เลือกทุกครั้งที่มีการสลับ หากแท็บแสดง ข้อมูลไดนามิก — อัตราแลกเปลี่ยน การแจ้งเตือน สถานะผู้ใช้ — viewWillAppear เป็นสถานที่ที่เหมาะสำหรับการอัปเดต
viewWillAppear แก้ปัญหางานเฉพาะหลายอย่างที่ไม่สามารถหรือไม่เหมาะสมที่จะดำเนินการในเมธอดอื่น มาดูงานหลักกัน
การใช้งานที่พบบ่อยที่สุดของ viewWillAppear คือการโหลด UITableView หรือ UICollectionView ซ้ำทุกครั้งที่หน้าจอปรากฏ หากข้อมูลอาจเปลี่ยนแปลงบนหน้าจอก่อนหน้า (เพิ่มรายการ เปลี่ยนสถานะ) การเรียก reloadData ใน viewWillAppear รับประกันว่าผู้ใช้เห็นข้อมูลล่าสุด
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
viewModel.synchronize()
tableView.reloadData()
}
ใน viewWillAppear สะดวกในการกำหนดลักษณะของ NavigationBar: ซ่อนหรือแสดง เปลี่ยนสี ตั้งค่าชื่อเรื่องขนาดใหญ่ หากหน้าจอต่างกันมีสไตล์ 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 สิ่งนี้ป้องกัน ตัวจัดการที่ไม่จำเป็น เมื่อหน้าจอไม่ทำงานและป้องกันการรั่วไหลของหน่วยความจำ
หากหน้าจอสามารถถูกซ่อนโดยแอปหรือย่อเล็กสุด viewWillAppear เป็นสถานที่สะดวกสำหรับการกู้คืนสถานะ UI: สลับส่วน กู้คืนตำแหน่งเลื่อน รีเซ็ตการเปลี่ยนแปลงชั่วคราว ผู้ใช้ จะได้รับหน้าจอในสถานะที่คาดเดาได้ทุกครั้งที่ปรากฏ
บนหน้าจอที่แสดงตัวนับข้อความที่ยังไม่ได้อ่าน การให้คะแนน หรือการแจ้งเตือน viewWillAppear เป็นสถานที่ที่เหมาะสมสำหรับการอัปเดต หากผู้ใช้อาจเปลี่ยนจำนวนบนหน้าจออื่น การคำนวณใหม่และการอัปเดต UITabBarItem.badgeValue หรือตัวบ่งชี้ที่กำหนดเองจะถูกเรียกที่นี่ สิ่งนี้รับประกันว่าผู้ใช้จะเห็นตัวเลขล่าสุดเสมอไม่ว่าพวกเขาจะอยู่บนหน้าจออื่นนานเท่าใด
ควรให้ความสนใจเป็นพิเศษกับการทำงานกับ collectionView: หากข้อมูลบนหน้าจอแสดงเป็นตารางที่มีเซลล์ซึ่งมีตัวนับหรือสถานะ การอัปเดตใน viewWillAppear ควร เลือกเฉพาะ แทนที่จะใช้ reloadData ทั้งหมด ให้ใช้ reloadItemsAtIndexPaths สำหรับเซลล์ที่มองเห็นเพื่อหลีกเลี่ยงการกระพริบและการสูญเสียตำแหน่งเลื่อน
การเข้าใจความแตกต่างระหว่าง viewWillAppear และ viewDidLoad เป็นพื้นฐานของสถาปัตยกรรม UIViewController ที่ถูกต้อง เมธอดเหล่านี้มีความถี่ในการเรียก บริบท และวัตถุประสงค์ที่แตกต่างกัน
viewDidLoad ถูกเรียกครั้งเดียวและเหมาะสำหรับการกำหนดค่าที่ไม่เปลี่ยนแปลงตามเวลา: การลงทะเบียนเซลล์ การตั้งค่าตัวแทน การเริ่มต้นค่าคงที่ viewWillAppear ถูกเรียกทุกครั้งที่ปรากฏและเหมาะสำหรับการดำเนินการที่ต้องทำซ้ำ: อัปเดตข้อมูล กำหนดค่าองค์ประกอบที่มองเห็น ซิงโครไนซ์สถานะ
| ลักษณะ | viewDidLoad | viewWillAppear |
|---|---|---|
| ความถี่ | ครั้งเดียว | ทุกครั้งที่ปรากฏ |
| View ปรากฏ | ไม่ | ไม่ (กำลังจะปรากฏ) |
| ขนาดของ View | ไม่สุดท้าย | สุดท้าย |
| เหมาะสมสำหรับ | การตั้งค่าครั้งเดียว | การอัปเดตและการซิงโครไนซ์ |
| แอนิเมชัน | ไม่สามารถใช้ได้ | พารามิเตอร์ animated |
กฎทอง: หากการดำเนินการควรทำเพียงครั้งเดียว — วางใน viewDidLoad หากควรทำทุกครั้งที่กลับมาที่หน้าจอ — วางใน viewWillAppear
การใช้ที่ไม่ถูกต้อง ของ viewWillAppear อาจนำไปสู่ปัญหาด้านประสิทธิภาพ การอัปเดตที่มากเกินไป และสถานะอินเทอร์เฟซที่ไม่สอดคล้องกัน มาดูข้อผิดพลาดที่พบบ่อยที่สุดกัน
ข้อผิดพลาดแรก — การทำซ้ำตรรกะจาก viewDidLoad หากคุณลงทะเบียนเซลล์ตารางทั้งใน viewDidLoad และ viewWillAppear การลงทะเบียนจะถูกดำเนินการหลายครั้ง แม้ว่าการตั้งค่าครั้งเดียวก็เพียงพอ ย้ายการกำหนดค่า ครั้งเดียว ทั้งหมดไปที่ viewDidLoad
ข้อผิดพลาดที่สอง — reloadData โดยไม่มีเงื่อนไขทุกครั้งที่ปรากฏ หากข้อมูลไม่เปลี่ยนแปลง การโหลดตารางซ้ำทำให้เกิดการสอบถามแหล่งข้อมูลโดยไม่จำเป็นและการวาดเซลล์ใหม่ ซึ่งลดประสิทธิภาพ ตรวจสอบว่า สถานะ เปลี่ยนแปลงจริงหรือไม่ก่อนเรียก reloadData
ข้อผิดพลาดที่สาม — การทำงานกับคำขอเครือข่ายโดยไม่พิจารณาว่าหน้าจออาจถูกซ่อนอีกครั้งก่อนที่คำขอจะเสร็จสมบูรณ์ หากคุณเริ่มคำขอ URLSession ใน viewWillAppear และผู้ใช้ไปยังหน้าจออื่นทันที ผลลัพธ์อาจถูกนำไปใช้กับ View ที่ซ่อนอยู่แล้ว ใช้งานที่ ยกเลิกได้ หรือตรวจสอบ isViewLoaded และ window ก่อนอัปเดต
ข้อผิดพลาดที่สี่ — ลืมเรียก super การไม่เรียก super.viewWillAppear อาจทำให้พฤติกรรมของคอนโทรลเลอร์หลัก (UINavigationController, UITabBarController) เสียหายและนำไปสู่การจัดการท่าทางและการเปลี่ยนผ่านที่ไม่ถูกต้อง super ควรถูกเรียกเสมอ
ข้อผิดพลาดที่ห้า — การแก้ไขข้อจำกัดโดยไม่เรียก layoutIfNeeded หากคุณเปลี่ยนข้อจำกัดโดยโปรแกรมใน viewWillAppear UIKit จะไม่นำไปใช้ทันที — การเปลี่ยนแปลงจะสะสมจนกระทั่งการผ่าน layout ครั้งถัดไป สำหรับการนำการเปลี่ยนแปลงไปใช้ทันทีหลังจากแก้ไขข้อจำกัด ให้เรียก view.layoutIfNeeded() สิ่งนี้สำคัญโดยเฉพาะเมื่อปรับความสูงขององค์ประกอบที่ขึ้นอยู่กับเนื้อหา
ข้อผิดพลาดที่หก — การพยายามทำแอนิเมชันใน viewWillAppear ดังที่กล่าวไว้ข้างต้น UIKit ยังคงประมวลผลแอนิเมชันการเปลี่ยนผ่าน และแอนิเมชันของคุณอาจแข่งขันกับแอนิเมชันของระบบ หากคุณต้องการให้องค์ประกอบปรากฏพร้อมเอฟเฟกต์ ให้ใช้แอนิเมชันขาเข้าใน viewDidAppear และใน viewWillAppear ให้กำหนดค่าเฉพาะสถานะเริ่มต้น: ความโปร่งใส 0, transform ที่สเกล 0.8 เป็นต้น
ข้อผิดพลาดที่เจ็ด — การละเลยพารามิเตอร์ animated นักพัฒนาบางคนไม่ตรวจสอบค่า animated ใน viewWillAppear และดำเนินการที่ควรขึ้นอยู่กับการมีอยู่ของแอนิเมชัน ตัวอย่างเช่น การซ่อน NavigationBar เมื่อ animated = false สามารถทำได้โดยไม่มีแอนิเมชัน และเมื่อ animated = true — มีแอนิเมชัน เพื่อให้การเปลี่ยนผ่านดูราบรื่น ส่งพารามิเตอร์ animated ไปยังเมธอด UIKit ที่เหมาะสมเสมอ
ข้อผิดพลาดที่แปด — การแก้ไข UI เมื่อหน้าจอไม่ปรากฏ หากคุณเริ่มคำขอเครือข่ายใน viewWillAppear และบล็อกเสร็จสมบูรณ์ของมันอัปเดต UI เมื่อหน้าจออาจหายไปแล้ว ผู้ใช้จะเห็นการกระพริบหรือสถานะที่ไม่สอดคล้องกัน ตรวจสอบ isViewLoaded และ window ก่อนอัปเดต UI ในคลosure เสมอ การกระทำง่าย ๆ นี้ป้องกันการขัดข้องและการวาดอินเทอร์เฟซซ้ำโดยไม่จำเป็น
คำถามที่พบบ่อย
viewWillAppear ถูกเรียกก่อนที่แอนิเมชันการปรากฏจะเริ่มขึ้น เมื่อ View ยังไม่ปรากฏ viewDidAppear ถูกเรียกหลังจากแอนิเมชันเสร็จสมบูรณ์ เมื่อหน้าจอแสดงเต็มที่และพร้อมสำหรับการโต้ตอบ
ภายใต้ สภาวะปกติ viewWillAppear จะถูกเรียกเสมอเมื่อหน้าจอปรากฏ ข้อยกเว้นคือการบังคับปิดแอป ซึ่ง UIKit ไม่มีเวลาเรียกเมธอดวงจรชีวิต
ใช่ จำเป็นอย่างยิ่ง UIKit ใช้การเรียกนี้เพื่อประสานงานภายในกับ UINavigationController และ UITabBarController หากไม่มี super ท่าทางและแอนิเมชันการเปลี่ยนผ่านอาจเสียหาย
ทุกครั้งที่สลับแท็บ UIKit เรียก viewWillAppear บนคอนโทรลเลอร์ของแท็บที่เลือกทันทีหลังจากที่ผู้ใช้แตะไอคอนที่เกี่ยวข้องใน TabBar
ใช้ คุณสมบัติของคอนโทรลเลอร์ หรือแหล่งข้อมูลที่ใช้ร่วมกัน ก่อนเรียก popViewController ให้ตั้งค่าที่ต้องการบนคอนโทรลเลอร์ก่อนหน้า และค่าจะพร้อมใช้งานใน viewWillAppear ของมัน
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม