อัพเดทล่าสุด (Xcode 10+ / Swift 4.2+)
บทความนี้ไม่เป็นอันตรายสำหรับทุกคนที่ยินดีที่จะเข้าใจตรรกะที่อยู่เบื้องหลังวิธีการต่าง ๆ ที่นำเสนอสำหรับหลายปีที่ผ่านมา ในขณะเดียวกันตั้งแต่Xcode 10 แนวทางแรกของ Swift 4.2 จะถูกคัดค้านและไม่ได้รับการสนับสนุนอีกต่อไป (เช่นจะไม่มีผลหากคุณพยายามใช้งาน) มันยังคงถูกเรียกสำหรับข้อมูลของคุณเพื่อทำความเข้าใจเกี่ยวกับเหตุผลที่อยู่เบื้องหลังการPlist.info
ตั้งค่าสถานะและการปรับแต่งการปฏิบัติที่ดีขึ้น
การชี้แจงที่สำคัญ
มันสำคัญมากที่จะต้องเข้าใจสองวิธีในการปรับแต่งลักษณะที่ปรากฏของแถบสถานะ พวกเขาแตกต่างกันและไม่ควรผสม
วิธีการแรก - สีเดียวสำหรับทั้งแอป (เลิกใช้ตั้งแต่ iOS7)
ใน info.plist คุณจะค้นหาหรือสร้างรหัสที่เรียกว่า
View controller-based status bar appearance
และตั้งค่าให้NO
มันทำอะไร มันเป็นหลักกำหนดตั้งค่าที่กล่าวว่าในใบสมัครของคุณปรากฏแถบสถานะไม่ได้ถูกกำหนดเป็นรายบุคคลโดยแต่ละตัวควบคุมมุมมอง นี่เป็นสิ่งสำคัญที่ต้องเข้าใจ ซึ่งหมายความว่าคุณมีการตั้งค่าที่เหมือนกันสำหรับแอพทั้งหมดสำหรับทุกหน้าจอ มีสองการตั้งค่า: default
ซึ่งเป็นข้อความสีดำบนพื้นหลังสีขาวหรือlightContent
ซึ่งเป็นข้อความสีขาวบนพื้นหลังสีดำ
ให้เป็นหนึ่งในชุดของเหล่านี้ขึ้น ( หนึ่งในการตั้งค่าสำหรับหน้าจอทั้งหมด ):
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
application.statusBarStyle = .lightContent // .default
return true
}
วิธีนี้คุณไม่จำเป็นต้องสร้างการตั้งค่านี้อีกครั้งบนแต่ละคอนโทรลเลอร์มุมมอง อย่างไรก็ตามคุณสามารถใช้วิธีนี้เพื่อเปลี่ยนรูปลักษณ์โดยสมัครใจ
วิธีที่สอง - แต่ละสีสำหรับแต่ละมุมมองคอนโทรลเลอร์
นี่คือสิ่งที่ตรงกันข้าม เพื่อให้มันใช้งานได้โปรดไปที่ info.plist และตั้งค่า
View controller-based status bar appearance
ถึงใช่
วิธีนี้ทุกครั้งที่มีการเปิดตัวควบคุมมุมมองใหม่ลักษณะแถบสถานะจะถูกตั้งค่าแยกต่างหากหากคุณแทรกการใช้งานนี้ในแต่ละUIViewController
อินสแตนซ์ที่คุณต้องการ:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent // .default
}
คุณมีเหมือนกันในตอนแรกตั้งค่าสไตล์มืดหรือสว่างสำหรับแถบสถานะแต่ละรายการเป็นคอนโทรลเลอร์มุมมอง
UIKit มีการเรียกคุณสมบัตินี้ในสองสถานการณ์:
- เมื่อเริ่มต้นของหน้าจอเมื่อ UI กำลังเตรียม
- เมื่อโทรเข้ามา
setNeedsStatusBarAppearanceUpdate()
ในรหัส
ในกรณีหลังคุณมีสิทธิ์จัดการลักษณะที่ปรากฏของแถบสถานะด้วยรหัสต่อไปนี้:
var isDark = false {
didSet {
setNeedsStatusBarAppearanceUpdate()
}
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return isDark ? .lightContent : .default
}
func toggleAppearance() {
isDark.toggle()
}
จากนั้นเมื่อใดก็ตามที่คุณโทรtoggleAppearance()
การเปลี่ยนรูปแบบของแถบสถานะจะถูกเรียกใช้
วิธีที่สาม - แฮ็ค!
มีแฮ็คที่อนุญาตให้เข้าถึงแถบสถานะโดยตรง:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView {
statusBar.backgroundColor = UIColor.blue
}
return true
}
ทำไมแฮ็ค หากคุณต้องการสีแถบสถานะอื่นที่ไม่ใช่สีดำหรือสีขาวคุณใช้ API ที่ไม่มีเอกสาร คุณได้รับstatusBar
วัตถุโดยใช้ KVC และตั้งค่าสีพื้นหลัง วัตถุที่คุณได้มาด้วยวิธีนี้คือUIStatusBar
ซึ่งได้มาจากUIView
และจึงสนับสนุนbackgroundColor
คุณสมบัติตามธรรมชาติ สิ่งนี้สกปรกไม่ถูกกฎหมาย แต่จนถึงตอนนี้ก็เป็นวิธีเดียวในการตั้งค่าสีที่กำหนดเองสำหรับแถบสถานะ (ไม่ได้คำนึงถึงUINavigationBar
วิธีการทางบัญชีซึ่งช่วยให้สามารถปรับแต่งรูปลักษณ์ของแถบนำทาง + สถานะทั้งหมด) อาจทำให้แอปของคุณถูกปฏิเสธ แต่บางทีคุณอาจโชคดี และหากคุณอยู่ในสถานการณ์ที่ซับซ้อนบางอย่าง (เช่นลำดับชั้นของซ้อนกันการนำทางของเด็กและตัวควบคุมมุมมอง) สิ่งนี้อาจเป็นเพียงวิธีเดียวหรืออย่างน้อยก็เป็นวิธีที่ยุ่งยากน้อยกว่าในการปรับแต่งลักษณะแถบสถานะ (ตัวอย่างเช่นเพื่อทำให้โปร่งใส)
Xcode 10+, Swift 4.2
ไม่มีทางเลือกอีกต่อไป: นักพัฒนาควรให้แต่ละตัวควบคุมมุมมองกำหนดลักษณะที่ปรากฏของแถบสถานะโดยการตั้งค่าสถานะเป็นYES (หรือละเว้นการกระทำนี้เนื่องจากเป็นค่าเริ่มต้นของ YES) และทำตามคำแนะนำด้านบน
โบนัส
โซลูชันที่ใช้การแฮ็กคุณอาจ (แม้ว่าจะไม่ได้รับการสนับสนุน) ใช้ในสถานการณ์ที่ซับซ้อนเพื่อเปลี่ยนลักษณะของแถบสถานะโดยสมัครใจในทุกขั้นตอน สีฉลาดวิธีการต่อไปนี้ทำสิ่งที่คุณสามารถทำได้ด้วยวิธีการปกติ คุณสามารถปรับได้ตามความต้องการของคุณ
extension UIViewController {
func setStatusBarStyle(_ style: UIStatusBarStyle) {
if let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView {
statusBar.backgroundColor = style == .lightContent ? UIColor.black : .white
statusBar.setValue(style == .lightContent ? UIColor.white : .black, forKey: "foregroundColor")
}
}
}