วิธีรับความสูงของแถบสถานะ iOS โดยทางโปรแกรม


277

ฉันรู้ว่าปัจจุบันแถบสถานะ (พร้อมเวลาแบตเตอรี่และการเชื่อมต่อเครือข่าย) ที่ด้านบนของ iPhone / iPad คือ 20 พิกเซลสำหรับหน้าจอที่ไม่ใช่เรตินาและ 40 พิกเซลสำหรับหน้าจอเรติน่า แต่เพื่อพิสูจน์แอปในอนาคตของฉัน เพื่อให้สามารถระบุได้โดยไม่มีค่าการเข้ารหัสยาก เป็นไปได้หรือไม่ที่จะคำนวณความสูงของแถบสถานะโดยทางโปรแกรม?

คำตอบ:


506

[UIApplication sharedApplication].statusBarFrame.size.height. แต่เนื่องจากขนาดทั้งหมดมีจุดไม่ใช่เป็นพิกเซลความสูงของแถบสถานะจะเท่ากับ 20 เสมอ

ปรับปรุง การเห็นคำตอบนี้ถือว่ามีประโยชน์ฉันควรทำอย่างละเอียด

ความสูงของแถบสถานะคือเท่ากับ 20.0f คะแนนยกเว้นกรณีต่อไปนี้:

  • แถบสถานะถูกซ่อนด้วยsetStatusBarHidden:withAnimation:เมธอดและความสูงเท่ากับ 0.0f คะแนน
  • ตามที่ @Anton นี่ชี้ให้เห็นในระหว่างการโทรเข้าด้านนอกของแอปพลิเคชั่นโทรศัพท์หรือในระหว่างแถบสถานะการบันทึกเสียงสูงเท่ากับ 40.0f จุด

นอกจากนี้ยังมีกรณีแถบสถานะที่มีผลต่อความสูงของมุมมองของคุณ โดยปกติความสูงของมุมมองเท่ากับขนาดหน้าจอสำหรับการวางแนวที่กำหนดลบความสูงของแถบสถานะ อย่างไรก็ตามหากคุณเคลื่อนไหวแถบสถานะ (แสดงหรือซ่อน) หลังจากที่แสดงมุมมองแถบสถานะจะเปลี่ยนเฟรม แต่มุมมองจะไม่แสดงคุณจะต้องปรับขนาดมุมมองด้วยตนเองหลังจากภาพเคลื่อนไหวแถบสถานะ (หรือระหว่างภาพเคลื่อนไหวตั้งแต่ ความสูงของแถบสถานะตั้งค่าเป็นค่าสุดท้ายเมื่อเริ่มต้นการเคลื่อนไหว)

อัปเดต 2.นอกจากนี้ยังมีกรณีของการวางแนวส่วนติดต่อผู้ใช้ แถบสถานะไม่เคารพค่าปฐมนิเทศจึงสถานะค่าบาร์สูงสำหรับภาพโหมด[UIApplication sharedApplication].statusBarFrame.size.height(ใช่การวางแนวทางเริ่มต้นอยู่เสมอภาพไม่ว่าสิ่งที่ info.plist ของแอปกล่าวว่า) สำหรับภูมิทัศน์[UIApplication sharedApplication].statusBarFrame.size.width - เพื่อตรวจสอบการวางแนวทางปัจจุบัน UI เมื่อนอกUIViewControllerและไม่ให้ใช้self.interfaceOrientation[UIApplication sharedApplication].statusBarOrientation

อัปเดตสำหรับ iOS7 แม้ว่าสไตล์ภาพแถบสถานะจะเปลี่ยนไป แต่ก็ยังอยู่ที่นั่นเฟรมยังคงทำงานเหมือนเดิม พบที่น่าสนใจเพียงประมาณแถบสถานะฉันได้ - ฉันหุ้นของคุณUINavigationBar's กระเบื้องพื้นหลังจะได้รับการปูกระเบื้องเพื่อแถบสถานะเพื่อให้คุณสามารถบรรลุผลการออกแบบที่น่าสนใจบางหรือเพียงแค่สีแถบสถานะของคุณ สิ่งนี้จะไม่ส่งผลกระทบต่อความสูงของแถบสถานะ แต่อย่างใด

พื้นหลังที่ปูกระเบื้องของแถบการนำทางจะเรียงต่อกันเป็นแถบสถานะ


6
วิธีนี้ให้ผล 1024 (iOS7)
Marc

1
@MarcMosby โปรดดูการอัปเดตของฉัน จำปัญหานี้ได้แล้ว - ขอบคุณคุณ
Kyr Dunenkoff

2
ใช่อย่างที่ Marc ชี้ไปที่ iOS7 มันจะทำให้บางครั้ง 1024 และบางครั้งก็ 20 ดังนั้นนี่จึงไม่ใช่วิธีพิสูจน์ความโง่ของการกำหนดความสูงอีกต่อไป ฉันสงสัยว่านี่เป็นเพราะลักษณะที่โปร่งใสของแถบสถานะบน iOS 7 อาจเป็นไปได้ว่ามันจะเต็มหน้าจอก่อนแล้วจึงปรับขนาดตัวเอง ดังนั้นหากคุณตรวจสอบคำสั่งระหว่างการเปลี่ยนแปลงนี้คุณอาจได้รับค่าที่ไม่ถูกต้อง อาจจะเรียกวิธีนี้ด้วยความล่าช้าอาจช่วยใน iOS 7
Deepak GM

1
มีกรณีที่ความสูงของแถบสถานะอาจเป็นศูนย์ได้ หากสนับสนุนInterfaceOrientations () ส่งคืน UIInterfaceOrientation (ผลลัพธ์ที่ไม่ถูกต้อง แต่ไม่มีข้อผิดพลาดของคอมไพเลอร์) แทน UIInterfaceOrientationMask และมีการนำเสนอและยกเลิก viewcontroller ความสูงของแถบสถานะจะกลายเป็นศูนย์
Cymric

5
นอกจากนี้บนแถบสถานะของ iPhone X จะสูงขึ้น
ก่อน

98

ไปกับข้อเสนอแนะของมาร์ตินกับคำถาม: รับ iPhone แถบสถานะสูง

CGFloat AACStatusBarHeight()
{
    CGSize statusBarSize = [[UIApplication sharedApplication] statusBarFrame].size;
    return MIN(statusBarSize.width, statusBarSize.height);
}

และในสวิฟท์

func statusBarHeight() -> CGFloat {
    let statusBarSize = UIApplication.shared.statusBarFrame.size
    return Swift.min(statusBarSize.width, statusBarSize.height)
}

ดูเหมือนแฮ็ค แต่จริงๆแล้วมันค่อนข้างแข็ง อย่างไรก็ตามมันเป็นทางออกเดียวที่ทำงานได้

คำตอบเก่า

รหัสต่อไปนี้ซึ่งจะอยู่ในคลาสย่อยที่กำหนดเองของUIViewControllerคุณเกือบจะทำงานเพื่อสนับสนุนแนวนอน แต่ฉันสังเกตเห็นเคสมุม (เมื่อหมุนจากด้านขวา> ไม่ได้รับการสนับสนุนคว่ำลง> ซ้าย) ซึ่งมันไม่ทำงาน (เปลี่ยนความสูงและความกว้าง)

BOOL isPortrait = self.interfaceOrientation == UIInterfaceOrientationPortrait;
CGSize statusBarSize = [UIApplication sharedApplication].statusBarFrame.size;
CGFloat statusBarHeight = (isPortrait ? statusBarSize.height : statusBarSize.width);

สิ่งนี้ไม่ถูกต้อง ความสูงของแถบสถานะจะไม่เปลี่ยนแปลงเมื่อคุณหมุนอุปกรณ์ ความกว้างจะ แต่รหัสข้างต้นไม่ได้แสดงว่าไม่ได้เป็นคำถามเดิม
lehn0058

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

นี่เป็นปัญหาที่น่าสนใจที่ฉันได้เห็นตอนนี้เช่นกัน ดูเหมือนว่าฉันจะมีข้อผิดพลาดในด้านของ Apple แต่ยังต้องมีการคิด
lehn0058

2
@ lehn0058 ไม่ใช่ข้อผิดพลาด แต่เป็นวิธีที่ Apple จัดการกับบาร์ภายใน มันถูกแนบกับหน้าต่างและหน้าต่างนั้นหมุนได้โดยใช้การแปลง statusBarFrameจะถูกส่งกลับเป็นค่าก่อนที่จะเปลี่ยน
Leo Natan

1
มันดูดีขึ้นในฐานะสถานที่: Dvar statusBarHeight: CGFloat
Pablo A.

23

ลองสิ่งนี้:

CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;

1
ความสูงที่ส่งคืนในทิศทางที่แตกต่างกันนั้นแตกต่างกัน มันแปลกมาก
tGilani

1
ใช่ถ้าการหมุนเป็นแนวนอน - [[UIApplication sharedApplication] statusBarFrame] .size.height และ [[UIApplication sharedApplication] statusBarFrame] ค่า. size.width จะถูกเปลี่ยน
Guntis Treulands


10

ในขณะที่แถบสถานะมักสูงถึง 20 พอยต์ แต่อาจเป็นสองเท่าของจำนวนเงินในบางสถานการณ์:

  • เมื่อคุณอยู่ระหว่างการโทร (นั่นเป็นสถานการณ์ที่พบได้บ่อย)
  • เมื่อเครื่องบันทึกเสียงหรือ Skype หรือแอพที่คล้ายกันกำลังใช้ไมโครโฟนในพื้นหลัง
  • เมื่อเปิดใช้งานฮอตสปอตส่วนตัว

ลองใช้แล้วคุณจะเห็นด้วยตัวคุณเอง การทำฮาร์ดโค้ดความสูงถึง 20 พอยต์มักจะใช้งานได้

ดังนั้นฉันจึงตอบคำตอบของ H2CO3 ที่สอง:

statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;

10

แก้ไข iOS ที่ 11 วิธีที่จะทำงานออกว่าจะใส่ด้านบนของเนื้อหามุมมองของคุณเป็นของ UIView safeAreaLayoutGuideดูเอกสาร UIView

คำตอบ ไม่ถูกต้องหากคุณกำหนดเป้าหมายเป็น iOS 7 ขึ้นไปเอกสารสำหรับ UIViewController แนะนำว่าtopLayoutGuideคุณสมบัติของ viewController จะแสดงที่ด้านล่างของแถบสถานะหรือด้านล่างของแถบการนำทางหากสามารถมองเห็นได้ นั่นอาจเป็นการใช้งานและแน่นอนว่าการแฮ็กน้อยกว่าโซลูชั่นก่อนหน้านี้จำนวนมาก


5

อย่าลืมว่าเฟรมของแถบสถานะจะอยู่ในพื้นที่พิกัดของหน้าจอ! หากคุณเปิดใช้งานในโหมดแนวนอนคุณอาจพบว่ามีการสลับความกว้างและความสูง ฉันขอแนะนำให้คุณใช้รหัสรุ่นนี้แทนหากคุณรองรับการหมุนแนวนอน:

CGRect statusBarFrame = [self.window convertRect:[UIApplication sharedApplication].statusBarFrame toView:view];

จากนั้นคุณสามารถอ่านคุณสมบัติความสูงของ statusBarFrame ได้โดยตรง 'มุมมอง' ในอินสแตนซ์นี้ควรเป็นมุมมองที่คุณต้องการใช้ประโยชน์จากการวัดซึ่งเป็นไปได้มากว่าคอนโทรลเลอร์มุมมองรูทของหน้าต่างแอปพลิเคชัน

บังเอิญไม่เพียง แต่แถบสถานะอาจสูงขึ้นระหว่างการโทร แต่มันอาจเป็นศูนย์ได้หากแถบสถานะถูกซ่อนอย่างจงใจ


นี่ไม่ได้ให้ความสูงที่ถูกต้องกับฉัน แต่ฉันพบวิธีที่ต่างไปสำหรับฉัน: stackoverflow.com/a/16598350/242933
ma11hew28

ใช่นี่เป็นรหัสที่ค่อนข้างเก่าในตอนนี้ดังนั้นจึงอาจไม่มีคำตอบที่ถูกต้องอีกต่อไป โดยส่วนตัวแล้วฉันไม่จำเป็นต้องตรวจสอบความสูงของแถบสถานะอีกต่อไปด้วยเลย์เอาต์อัตโนมัติ
Ash

2

นี่เป็นวิธีที่รวดเร็วในการรับความสูงของแถบสถานะของหน้าจอ:

var screenStatusBarHeight: CGFloat {
    return UIApplication.sharedApplication().statusBarFrame.height
}

สิ่งเหล่านี้รวมอยู่ในฟังก์ชั่นมาตรฐานในโครงการของฉัน: https://github.com/goktugyil/EZSwiftExtensions



1
    var statusHeight: CGFloat!
    if #available(iOS 13.0, *) {
         statusHeight = UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame.height
    } else {
        // Fallback on earlier versions
        statusHeight = UIApplication.shared.statusBarFrame.height
    }


0

ฉันเพิ่งค้นพบวิธีที่ช่วยให้คุณไม่สามารถเข้าถึงความสูงของแถบสถานะได้โดยตรง แต่คำนวณได้

ความสูงของแถบนำทาง - topLayoutGuide length = ความสูงของแถบสถานะ

สวิฟท์:

let statusBarHeight = self.topLayoutGuide.length-self.navigationController?.navigationBar.frame.height

self.topLayoutGuide.lengthเป็นพื้นที่ด้านบนที่ครอบคลุมโดยแถบโปร่งแสงและself.navigationController?.navigationBar.frame.heightเป็นแถบโปร่งแสงที่ไม่รวมแถบสถานะซึ่งโดยปกติแล้วจะเป็น 44PT ดังนั้นโดยใช้วิธีนี้คุณสามารถคำนวณความสูงของแถบสถานะได้อย่างง่ายดายโดยไม่ต้องกังวลเกี่ยวกับการเปลี่ยนความสูงของแถบสถานะเนื่องจากการโทรศัพท์


สิ่งนี้ไม่ได้ผลself.topLayoutGuide.lengthคือ 0 ดังนั้นผลลัพธ์ที่ได้คือ -44
nambatee

@nambatee ฉันเชื่อว่ามันใช้งานไม่ได้อีกต่อไปเพราะฉันใช้ iOS 11 Apple ใช้ safeAreaInsets
Henry Ngan


-6

การใช้รหัสบรรทัดเดียวต่อไปนี้คุณสามารถรับความสูงของแถบสถานะในทิศทางใดก็ได้และหากมองเห็นได้หรือไม่

#define STATUS_BAR_HIGHT (
    [UIApplicationsharedApplication].statusBarHidden ? 0 : (
        [UIApplicationsharedApplication].statusBarFrame.size.height > 100 ?
            [UIApplicationsharedApplication].statusBarFrame.size.width :
            [UIApplicationsharedApplication].statusBarFrame.size.height
    )
)

มันเป็นมาโครที่เรียบง่าย แต่มีประโยชน์มากลองแค่นี้คุณไม่จำเป็นต้องเขียนโค้ดพิเศษใด ๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.