Cách lập trình lấy chiều cao thanh trạng thái iOS


277

Tôi biết rằng hiện tại thanh trạng thái (với thời gian, pin và kết nối mạng) ở đầu iPhone / iPad là 20 pixel cho màn hình không võng mạc và 40 pixel cho màn hình võng mạc, nhưng để chứng minh trong tương lai ứng dụng của tôi, tôi muốn để có thể xác định điều này mà không cần giá trị mã hóa cứng. Có thể tìm ra chiều cao của thanh trạng thái theo chương trình?

Câu trả lời:


506

[UIApplication sharedApplication].statusBarFrame.size.height. Nhưng vì tất cả các kích thước được tính bằng điểm, không phải bằng pixel, chiều cao của thanh trạng thái luôn bằng 20.

Cập nhật.Thấy câu trả lời này được coi là hữu ích, tôi nên giải thích.

Thực tế, chiều cao của thanh trạng thái bằng 20.0f điểm trừ các trường hợp sau:

  • thanh trạng thái đã bị ẩn với setStatusBarHidden:withAnimation: phương thức và chiều cao của nó bằng 0,0f điểm;
  • như @Anton ở đây đã chỉ ra, trong một cuộc gọi đến bên ngoài ứng dụng Điện thoại hoặc trong chiều cao thanh trạng thái phiên ghi âm bằng 40,0f điểm.

Ngoài ra còn có một trường hợp thanh trạng thái ảnh hưởng đến chiều cao của chế độ xem của bạn. Thông thường, chiều cao của khung nhìn bằng kích thước màn hình cho hướng đã cho trừ đi chiều cao của thanh trạng thái. Tuy nhiên, nếu bạn làm động thanh trạng thái (hiển thị hoặc ẩn nó) sau khi chế độ xem được hiển thị, thanh trạng thái sẽ thay đổi khung của nó, nhưng chế độ xem sẽ không , bạn sẽ phải thay đổi kích thước chế độ xem sau khi hoạt hình trên thanh trạng thái (hoặc trong khi hoạt hình chiều cao thanh trạng thái đặt thành giá trị cuối cùng khi bắt đầu hoạt hình).

Cập nhật 2. Cũng có trường hợp định hướng giao diện người dùng. Thanh trạng thái không tôn trọng các giá trị định hướng, thanh trạng thái như vậy, chiều cao giá trị cho chân dung chế độ là [UIApplication sharedApplication].statusBarFrame.size.height(vâng, định hướng mặc định luôn là chân dung, không có vấn đề gì info.plist ứng dụng của bạn nói), cho cảnh quan - [UIApplication sharedApplication].statusBarFrame.size.width. Để xác định hướng hiện tại của UI khi ở ngoài UIViewControllerself.interfaceOrientationkhông khả dụng, hãy sử dụng [UIApplication sharedApplication].statusBarOrientation.

Cập nhật cho iOS7. Mặc dù phong cách trực quan của thanh trạng thái đã thay đổi, nó vẫn ở đó, khung của nó vẫn hoạt động như cũ. Phát hiện thú vị về chỉ thanh trạng thái tôi - tôi phần: bạn UINavigationBar's lát gạch nền cũng sẽ được lát gạch để thanh trạng thái, vì vậy bạn có thể đạt được một số hiệu ứng thiết kế thú vị hay chỉ là màu sắc thanh trạng thái của bạn. Điều này cũng vậy, sẽ không ảnh hưởng đến chiều cao của thanh trạng thái theo bất kỳ cách nào.

Thanh điều hướng nền lát gạch cũng được lát thành thanh trạng thái


6
Phương pháp này mang lại 1024 (iOS7)
Marc

1
@MarcMosby, xem cập nhật của tôi. Ghi nhớ vấn đề này - cảm ơn bạn.
Kyr Dunenkoff

2
Vâng, như Marc đã chỉ trên iOS7, đôi khi nó có 1024 và 20 đôi khi. Vì vậy, đây không còn là một cách chứng minh ngu ngốc để xác định chiều cao. Tôi nghi ngờ điều này là do tính chất trong suốt của thanh trạng thái trên iOS 7. Có thể là, trước tiên, nó sẽ chuyển sang toàn màn hình và sau đó tự thay đổi kích thước. Vì vậy, nếu bạn truy vấn ứng dụng trong quá trình chuyển đổi này, bạn có thể nhận được giá trị sai. Có thể gọi phương thức này với độ trễ có thể giúp ích trên iOS 7.
Deepak GM

1
Có một trường hợp chiều cao thanh trạng thái có thể bằng không. Nếu được hỗ trợInterfaceOrientations () trả về UIInterfaceOrientation (kết quả không chính xác nhưng không có lỗi trình biên dịch) thay vì UIInterfaceOrientationMask và trình điều khiển chế độ xem được hiển thị và loại bỏ, chiều cao của thanh trạng thái sẽ bằng không.
Địa lan

5
Ngoài ra trên thanh trạng thái iPhone X sẽ cao hơn.
trước

98

Đi với đề xuất của Martin cho câu hỏi: Nhận chiều cao thanh trạng thái iPhone .

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

Và trong Swift

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

Nó có vẻ như là một hack, nhưng nó thực sự khá vững chắc. Dù sao, đó là giải pháp làm việc duy nhất.

Câu trả lời cũ

Đoạn mã sau, sẽ đi vào lớp con tùy chỉnh của bạn UIViewController, gần như đã hoạt động để hỗ trợ cảnh quan. Nhưng, tôi nhận thấy một trường hợp góc (khi xoay từ phải> lộn ngược không được hỗ trợ> trái) mà nó không hoạt động (chuyển chiều cao và chiều rộng).

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

Điều này LAF không đúng. Chiều cao của thanh trạng thái không thay đổi khi bạn xoay thiết bị. Chiều rộng sẽ, nhưng mã ở trên không cho thấy điều đó, cũng không phải là câu hỏi ban đầu.
lehn0058

1
Bạn đúng rằng "chiều cao của thanh trạng thái không thay đổi khi bạn xoay thiết bị." Nhưng, như Ash đã trả lời , "ở chế độ ngang, bạn có thể thấy rằng chiều rộng và chiều cao bị tráo đổi." Các mã ở trên có tính đến điều đó.
ma11hew28

Đây là một vấn đề thú vị mà tôi đã thấy bây giờ là tốt. Nó có vẻ như là một lỗi đối với tôi về phía Apple, nhưng vẫn cần phải được tính đến.
lehn0058

2
@ lehn0058 Đây không phải là lỗi, đó là cách Apple xử lý thanh bên trong. Nó được gắn vào một cửa sổ và cửa sổ đó được xoay bằng cách sử dụng một biến đổi. Giá trị statusBarFrameđược trả về là giá trị trước khi biến đổi.
Leo Natan

1
Nó trông tốt hơn như một tài sản: Dvar statusBarHeight: CGFloat
Pablo A.

23

Thử cái này:

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

1
chiều cao được trả về theo các hướng khác nhau là khác nhau. thật lạ
tGilani

1
Có, nếu xoay là ngang - [[UIApplication sharedApplication] statusBarFrame] .size.height và [[UIApplication sharedApplication] statusBarFrame] .size.
Guntis Treulands

21

Swift 3 hoặc Swift 4:

UIApplication.shared.statusBarFrame.height

10

Mặc dù thanh trạng thái thường cao 20pt, nhưng nó có thể gấp đôi số tiền đó trong một số trường hợp:

  • khi bạn đang ở giữa một cuộc gọi điện thoại (đó là một tình huống khá phổ biến);
  • khi máy ghi âm hoặc Skype hoặc ứng dụng tương tự đang sử dụng micrô ở chế độ nền;
  • khi Điểm truy cập cá nhân được kích hoạt;

Chỉ cần thử nó, và bạn sẽ thấy cho chính mình. Mã hóa chiều cao đến 20pt thường sẽ hoạt động, cho đến khi không.

Vì vậy, tôi thứ hai câu trả lời của H2CO3:

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

10

EDIT Cách iOS 11 để tìm ra vị trí đặt đầu nội dung chế độ xem của bạn là Tài liệusafeAreaLayoutGuide Xem UIView của UIView .

TRẢ LỜI ĐÁP ÁN Nếu bạn đang nhắm mục tiêu iOS 7+, Tài liệu dành cho UIViewControll khuyên rằng thuộc tính của viewContoder topLayoutGuidecung cấp cho bạn phần dưới cùng của thanh trạng thái hoặc dưới cùng của thanh điều hướng, nếu nó cũng hiển thị. Điều đó có thể được sử dụng, và chắc chắn là ít hack hơn nhiều giải pháp trước đây.


5

Đừng quên rằng khung của thanh trạng thái sẽ nằm trong không gian tọa độ của màn hình! Nếu bạn khởi chạy ở chế độ ngang, bạn có thể thấy rằng chiều rộng và chiều cao bị tráo đổi. Tôi thực sự khuyên bạn nên sử dụng phiên bản mã này thay thế nếu bạn hỗ trợ định hướng ngang:

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

Sau đó, bạn có thể đọc thuộc tính chiều cao của statusBarFrame trực tiếp. 'Chế độ xem' trong trường hợp này phải là chế độ xem mà bạn muốn sử dụng các phép đo, rất có thể là bộ điều khiển chế độ xem gốc của cửa sổ ứng dụng.

Ngẫu nhiên, không chỉ thanh trạng thái có thể cao hơn trong các cuộc gọi điện thoại, nó cũng có thể bằng 0 nếu thanh trạng thái bị cố tình ẩn.


Điều này đã không cho tôi chiều cao chính xác. Nhưng, tôi đã tìm thấy cách khác phù hợp với mình: stackoverflow.com/a/16598350/242933
ma11hew28

Vâng đây là mã khá cũ bây giờ vì vậy có lẽ không còn là một câu trả lời hợp lệ. Cá nhân tôi không còn có nhu cầu kiểm tra chiều cao của thanh trạng thái, nhờ bố trí tự động.
Tro

2

Dưới đây là cách Swift để lấy chiều cao thanh trạng thái màn hình:

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

Chúng được bao gồm như là một chức năng tiêu chuẩn trong một dự án của tôi: https://github.com/goktugyil/EZSwiftExtensions


2

Đối với iOS 13, bạn có thể sử dụng:

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

Tôi chỉ tìm thấy một cách cho phép bạn không truy cập trực tiếp vào chiều cao của thanh trạng thái, nhưng tính toán nó.

Chiều cao thanh điều hướng - topLayoutGuide length = chiều cao thanh trạng thái

Nhanh:

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

self.topLayoutGuide.lengthlà khu vực trên cùng được bao phủ bởi thanh mờ và self.navigationController?.navigationBar.frame.heightlà thanh mờ không bao gồm thanh trạng thái, thường là 44pt. Vì vậy, bằng cách sử dụng phương pháp này, bạn có thể dễ dàng tính toán chiều cao của thanh trạng thái mà không phải lo lắng về việc thay đổi chiều cao của thanh trạng thái do các cuộc gọi điện thoại.


Điều này không hoạt động, self.topLayoutGuide.lengthlà 0 nên kết quả cuối cùng là -44.
nambatee

@nambatee Tôi tin rằng nó không còn hoạt động nữa vì tôi là iOS 11 Apple sử dụng safeAreaInsets
Henry Ngân


-6

Sử dụng mã dòng đơn sau đây, bạn có thể nhận được chiều cao của thanh trạng thái theo bất kỳ hướng nào và cũng có thể hiển thị hay không

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

Nó chỉ là một macro đơn giản nhưng rất hữu ích, hãy thử điều này, bạn không cần phải viết thêm bất kỳ mã nào

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.