Bagaimana secara pemrograman mendapatkan ketinggian bilah status iOS


277

Saya tahu bahwa saat ini bilah status (dengan waktu, baterai, dan koneksi jaringan) di bagian atas iPhone / iPad adalah 20 piksel untuk layar non-retina dan 40 piksel untuk layar retina, tetapi untuk bukti di masa depan aplikasi saya, saya ingin untuk dapat menentukan ini tanpa nilai pengkodean keras. Apakah mungkin untuk mengetahui ketinggian bilah status secara terprogram?

Jawaban:


506

[UIApplication sharedApplication].statusBarFrame.size.height. Tetapi karena semua ukuran dalam titik, bukan dalam piksel, tinggi bilah status selalu sama dengan 20.

Memperbarui. Melihat jawaban ini dianggap membantu, saya harus menguraikan.

Tinggi bilah status, memang, sama dengan 20.0f poin kecuali kasus berikut:

  • status bar telah disembunyikan dengan setStatusBarHidden:withAnimation:metode dan tingginya sama dengan 0,0f poin;
  • seperti yang ditunjukkan @Anton di sini, selama panggilan masuk di luar aplikasi Telepon atau selama bilah status sesi perekaman suara sama dengan 40.0f poin.

Ada juga kotak status yang memengaruhi ketinggian tampilan Anda. Biasanya, ketinggian tampilan sama dengan dimensi layar untuk orientasi yang diberikan dikurangi ketinggian bilah status. Namun, jika Anda menghidupkan bilah status (tampilkan atau sembunyikan) setelah tampilan ditampilkan, bilah status akan mengubah bingkainya, tetapi tampilan tidak akan , Anda harus mengubah ukuran tampilan secara manual setelah animasi bilah status (atau selama animasi sejak tinggi bilah status ditetapkan ke nilai akhir pada awal animasi).

Pembaruan 2. Ada juga kasus orientasi antarmuka pengguna. Bilah status tidak menghormati nilai orientasi, sehingga nilai tinggi bilah status untuk mode potret adalah [UIApplication sharedApplication].statusBarFrame.size.height(ya, orientasi default selalu tegak, tidak peduli apa yang dikatakan oleh aplikasi Anda.), Untuk lansekap - [UIApplication sharedApplication].statusBarFrame.size.width. Untuk menentukan orientasi UI saat ini ketika di luar UIViewControllerdan self.interfaceOrientationtidak tersedia, gunakan [UIApplication sharedApplication].statusBarOrientation.

Perbarui untuk iOS7. Meskipun gaya visual status bar berubah, masih ada di sana, bingkainya tetap berperilaku sama. Satu-satunya yang menarik menemukan status bar aku - aku share: Anda UINavigationBar's ubin latar belakang juga akan ubin status bar, sehingga Anda dapat mencapai beberapa efek desain yang menarik atau hanya warna status bar Anda. Ini juga tidak akan memengaruhi ketinggian bilah status dengan cara apa pun.

Latar belakang ubin navigasi bar juga ubin ke status bar


6
Metode ini menghasilkan 1024 (iOS7)
Marc

1
@MarcMosby, lihat pembaruan saya. Teringat masalah ini - terima kasih.
Kyr Dunenkoff

2
Ya, seperti yang ditunjukkan Marc pada iOS7, terkadang diperlukan 1024 dan 20 terkadang. Jadi ini bukan lagi cara bukti bodoh untuk menentukan ketinggian. Saya ragu ini karena sifat transparan dari status bar di iOS 7. Bisa jadi itu, pertama-tama pergi ke layar penuh dan kemudian mengubah ukurannya sendiri. Jadi, jika Anda mengajukan permintaan selama transisi ini, Anda mungkin mendapatkan nilai yang salah. Mungkin memanggil metode ini dengan penundaan mungkin membantu di iOS 7.
Deepak GM

1
Ada kasus di mana ketinggian bilah status bisa nol. Jika didukungInterfaceOrientations () mengembalikan UIInterfaceOrientation (hasil yang salah tetapi tidak ada kesalahan kompiler) bukannya UIInterfaceOrientationMask dan viewcontroller disajikan dan diberhentikan, tinggi bilah status akan menjadi nol.
Cymric

5
Juga di bilah status iPhone X akan lebih tinggi.
sebelum

98

Pergi dengan saran Martin untuk pertanyaan: Dapatkan Status iPhone Bar Tinggi .

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

Dan di Swift

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

Sepertinya ini adalah retasan, tetapi sebenarnya cukup solid. Bagaimanapun, itu satu-satunya solusi yang berfungsi.

Jawaban Lama

Kode berikut, yang akan masuk dalam subkelas kustom Anda UIViewController, hampir berfungsi untuk mendukung lansekap. Tapi, saya perhatikan kasing sudut (ketika berputar dari kanan> terbalik terbalik> kiri) yang tidak berfungsi (beralih tinggi & lebar).

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

Ini tidak benar. Ketinggian bilah status tidak berubah ketika Anda memutar perangkat. Lebar akan, tetapi kode di atas tidak menunjukkan itu, juga bukan pertanyaan aslinya.
lehn0058

1
Anda benar bahwa "ketinggian bilah status tidak berubah ketika Anda memutar perangkat." Tetapi, ketika Ash menjawab , "dalam mode lansekap, Anda mungkin menemukan bahwa lebar dan tinggi ditukar." Kode di atas memperhitungkannya.
ma11hew28

Ini adalah masalah menarik yang telah saya lihat sekarang juga. Sepertinya bug bagi saya di pihak Apple, tetapi masih perlu dipertanggungjawabkan.
lehn0058

2
@ lehn0058 Ini bukan bug, melainkan bagaimana Apple menangani bilah secara internal. Itu dilampirkan ke jendela dan jendela itu diputar menggunakan transformasi. Ini statusBarFramedikembalikan sebagai nilai sebelum transformasi.
Leo Natan

1
Terlihat lebih baik sebagai properti: Dvar statusBarHeight: CGFloat
Pablo A.

23

Coba ini:

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

1
ketinggian yang dikembalikan dalam orientasi berbeda berbeda. itu aneh
tGilani

1
Ya, jika rotasi lansekap - [[UIApplication sharedApplication] statusBarFrame] .size.height dan [[UIApplication sharedApplication] statusBarFrame] .size.width nilai diubah.
Guntis Treulands

21

Swift 3 atau Swift 4:

UIApplication.shared.statusBarFrame.height

10

Sementara bilah status biasanya 20pt tinggi, itu bisa dua kali lipatnya dalam beberapa situasi:

  • ketika Anda berada di tengah-tengah panggilan telepon (itu skenario yang cukup umum);
  • ketika perekam suara, atau Skype, atau aplikasi serupa, menggunakan mikrofon di latar belakang;
  • ketika Personal Hotspot diaktifkan;

Coba saja, dan Anda akan melihatnya sendiri. Hardcoding ketinggian ke 20pt biasanya akan berfungsi, sampai tidak.

Jadi saya menjawab kedua H2CO3:

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

10

EDIT Cara iOS 11 untuk mengetahui di mana menempatkan bagian atas konten tampilan Anda adalah safeAreaLayoutGuideSee UIView's Documentation .

JAWABAN YANG TERJUTAN Jika Anda menargetkan iOS 7+, Dokumentasi untuk UIViewController menyarankan agar topLayoutGuideproperti viewController memberi Anda bagian bawah bilah status, atau bagian bawah bilah navigasi, jika itu juga terlihat. Itu mungkin berguna, dan tentu saja lebih sedikit peretasan dibandingkan banyak solusi sebelumnya.


5

Jangan lupa bahwa bingkai bilah status akan berada di ruang koordinat layar! Jika Anda meluncurkan dalam mode lansekap, Anda mungkin menemukan bahwa lebar dan tinggi ditukar. Saya sangat menyarankan Anda menggunakan versi kode ini jika Anda mendukung orientasi lanskap:

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

Anda kemudian dapat membaca properti tinggi statusBarFrame secara langsung. 'Tampilan' dalam contoh ini haruslah tampilan di mana Anda ingin menggunakan pengukuran, kemungkinan besar pengendali tampilan root jendela aplikasi.

Secara kebetulan, bilah status tidak hanya lebih tinggi selama panggilan telepon, bilah status juga dapat menjadi nol jika bilah status disembunyikan dengan sengaja.


Ini tidak memberi saya ketinggian yang benar. Tapi, saya menemukan cara berbeda yang bekerja untuk saya: stackoverflow.com/a/16598350/242933
ma11hew28

Ya ini kode yang cukup lama sekarang jadi mungkin bukan lagi jawaban yang valid. Secara pribadi saya tidak lagi perlu memeriksa ketinggian bilah status, berkat tata letak otomatis.
Ash


2

Untuk iOS 13 Anda dapat menggunakan:

UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame.height

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

Saya baru saja menemukan cara yang memungkinkan Anda tidak secara langsung mengakses ketinggian bilah status, tetapi menghitungnya.

Tinggi Bilah Navigasi - panjang topLayoutGuide = tinggi status bar

Cepat:

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

self.topLayoutGuide.lengthadalah area teratas yang dicakup oleh bilah tembus cahaya, dan self.navigationController?.navigationBar.frame.heightmerupakan bilah tembus cahaya yang tidak termasuk bilah status, yang biasanya 44pt. Jadi dengan menggunakan metode ini Anda dapat dengan mudah menghitung ketinggian bilah status tanpa khawatir tentang perubahan tinggi bilah status karena panggilan telepon.


Ini tidak berfungsi, self.topLayoutGuide.lengthadalah 0 sehingga hasilnya menjadi -44.
nambatee

@nambatee Saya percaya itu tidak berfungsi lagi karena saya iOS 11 Apple menggunakan safeAreaInsets
Henry Ngan


-6

Dengan menggunakan kode baris tunggal berikut, Anda dapat memperoleh ketinggian bilah status dalam orientasi apa pun dan juga jika terlihat atau tidak

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

Ini hanya makro yang sederhana namun sangat berguna coba saja ini Anda tidak perlu menulis kode tambahan

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.