So ermitteln Sie programmgesteuert die Höhe der iOS-Statusleiste

277

Ich weiß, dass die Statusleiste (mit Zeit, Akku und Netzwerkverbindung) oben auf dem iPhone / iPad derzeit 20 Pixel für Nicht-Retina-Bildschirme und 40 Pixel für Retina-Bildschirme beträgt, aber um meine App zukunftssicher zu machen, möchte ich dies ohne harte Codierungswerte bestimmen zu können. Ist es möglich, die Höhe der Statusleiste programmgesteuert zu ermitteln?

lehn0058
quelle

Antworten:

506

[UIApplication sharedApplication].statusBarFrame.size.height. Da jedoch alle Größen in Punkten und nicht in Pixeln angegeben sind, beträgt die Höhe der Statusleiste immer 20.

Aktualisieren. Da diese Antwort als hilfreich angesehen wird, sollte ich näher darauf eingehen.

Die Höhe der Statusleiste beträgt in der Tat 20,0 f Punkte, außer in folgenden Fällen:

  • Die Statusleiste wurde mit der setStatusBarHidden:withAnimation:Methode ausgeblendet und ihre Höhe entspricht 0,0 f Punkten.
  • Wie @Anton hier hervorhob, beträgt die Höhe der Statusleiste während eines eingehenden Anrufs außerhalb der Telefonanwendung oder während der Statusleiste der Tonaufzeichnungssitzung 40,0 f Punkte.

Es gibt auch einen Fall von Statusleisten, die sich auf die Höhe Ihrer Ansicht auswirken. Normalerweise entspricht die Höhe der Ansicht der Bildschirmgröße für die angegebene Ausrichtung abzüglich der Höhe der Statusleiste. Wenn Sie jedoch die Statusleiste animieren (anzeigen oder ausblenden), nachdem die Ansicht angezeigt wurde, ändert die Statusleiste ihren Rahmen, die Ansicht jedoch nicht . Sie müssen die Größe der Ansicht nach der Animation der Statusleiste (oder während der Animation seitdem manuell ändern) Die Höhe der Statusleiste wird zu Beginn der Animation auf den Endwert gesetzt.

Update 2. Es gibt auch einen Fall der Ausrichtung der Benutzeroberfläche. Statusleiste nicht respektiert den Orientierungswert, also Statusleiste Höhenwert für Portrait - Modus ist [UIApplication sharedApplication].statusBarFrame.size.height(ja, Standardausrichtung ist immer Porträt, egal , was Ihre Anwendung info.plist sagt), für Landschaft - [UIApplication sharedApplication].statusBarFrame.size.width. Verwenden Sie, um die aktuelle Ausrichtung der Benutzeroberfläche außerhalb UIViewControllerund self.interfaceOrientationnicht verfügbar zu bestimmen [UIApplication sharedApplication].statusBarOrientation.

Update für iOS7. Obwohl sich der visuelle Stil der Statusleiste geändert hat, ist er immer noch vorhanden, und sein Rahmen verhält sich immer noch gleich. Die einzige interessante Entdeckung über Statusleiste habe ich - ich teile: Ihr UINavigationBar‚s gekachelten Hintergrund wird auch auf Statusleiste mit Ziegeln gedeckt werden, so dass Sie einige interessante Design - Effekte erzielen oder einfach nur Ihre Statusleiste färben. Auch dies hat keinerlei Einfluss auf die Höhe der Statusleiste.

Der gekachelte Hintergrund der Navigationsleiste wird auch in die Statusleiste gekachelt

Kyr Dunenkoff
quelle
6
Diese Methode ergibt 1024 (iOS7)
Marc
1
@MarcMosby, siehe mein Update. Ich habe mich an dieses Problem erinnert - danke.
Kyr Dunenkoff
2
Ja, wie Marc auf iOS7 zeigte, werden manchmal 1024 und manchmal 20 angezeigt. Dies ist also keine narrensichere Methode zur Bestimmung der Höhe mehr. Ich bezweifle, dass dies an der Transparenz der Statusleiste unter iOS 7 liegt. Es kann sein, dass sie zuerst in den Vollbildmodus wechselt und dann die Größe ändert. Wenn Sie also während dieses Übergangs App-Abfragen durchführen, erhalten Sie möglicherweise den falschen Wert. Möglicherweise hilft das Aufrufen dieser Methode mit einer Verzögerung unter iOS 7.
Deepak GM
1
Es gibt einen Fall, in dem die Höhe der Statusleiste Null sein kann. Wenn supportInterfaceOrientations () anstelle von UIInterfaceOrientationMask UIInterfaceOrientation (falsches Ergebnis, aber kein Compilerfehler) zurückgibt und ein Viewcontroller angezeigt und geschlossen wird, wird die Höhe der Statusleiste Null.
Cymric
5
Auch auf dem iPhone X wird die Statusleiste höher sein.
vor dem
98

Gehen Sie mit Martins Vorschlag auf die Frage: Holen Sie sich die Höhe der iPhone-Statusleiste .

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

Und in Swift

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

Es scheint wie ein Hack, aber es ist eigentlich ziemlich solide. Auf jeden Fall ist es die einzige funktionierende Lösung.

Alte Antwort

Der folgende Code, der in Ihre benutzerdefinierte Unterklasse von passt UIViewController, hat fast zur Unterstützung der Landschaft beigetragen. Aber ich bemerkte ein Eckgehäuse (beim Drehen von rechts> nicht unterstützt auf den Kopf> links), für das es nicht funktionierte (Höhe und Breite umgeschaltet).

BOOL isPortrait = self.interfaceOrientation == UIInterfaceOrientationPortrait;
CGSize statusBarSize = [UIApplication sharedApplication].statusBarFrame.size;
CGFloat statusBarHeight = (isPortrait ? statusBarSize.height : statusBarSize.width);
ma11hew28
quelle
Das ist nicht richtig. Die Höhe der Statusleiste ändert sich nicht, wenn Sie das Gerät drehen. Die Breite würde, aber der obige Code zeigt das nicht, noch war das die ursprüngliche Frage.
lehn0058
1
Sie haben Recht, dass "sich die Höhe der Statusleiste beim Drehen des Geräts nicht ändert". Aber wie Ash antwortete : "Im Querformat können Sie feststellen, dass Breite und Höhe vertauscht sind." Der obige Code berücksichtigt dies.
ma11hew28
Dies ist ein interessantes Thema, das ich jetzt auch gesehen habe. Es sieht für mich auf Apples Seite wie ein Fehler aus, muss aber noch berücksichtigt werden.
lehn0058
2
@ lehn0058 Es ist kein Fehler, es ist, wie Apple die Leiste intern behandelt. Es wird an ein Fenster angehängt und dieses Fenster wird mithilfe einer Transformation gedreht. Das statusBarFramewird als Wert vor der Transformation zurückgegeben.
Leo Natan
1
Es sieht besser aus als eine Eigenschaft: Dvar statusBarHeight: CGFloat
Pablo A.
23

Versuche dies:

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

quelle
1
Die Höhe, die in verschiedenen Ausrichtungen zurückgegeben wird, ist unterschiedlich. das ist seltsam
Gilani
1
Ja, wenn die Rotation im Querformat erfolgt, werden die Werte [[UIApplication sharedApplication] statusBarFrame] .size.height und [[UIApplication sharedApplication] statusBarFrame] .size.width umgeschaltet.
Guntis Treulands
21

Swift 3 oder Swift 4:

UIApplication.shared.statusBarFrame.height
Wilson
quelle
10

Während die Statusleiste normalerweise 20pt hoch ist, kann sie in einigen Situationen doppelt so hoch sein:

  • wenn Sie sich mitten in einem Telefonat befinden (das ist ein ziemlich häufiges Szenario);
  • wenn der Diktiergerät oder Skype oder eine ähnliche App das Mikrofon im Hintergrund verwendet;
  • wenn der persönliche Hotspot aktiviert ist;

Probieren Sie es einfach aus und Sie werden es selbst sehen. Das Hardcodieren der Höhe auf 20pt funktioniert normalerweise, bis dies nicht mehr der Fall ist.

Also stimme ich der Antwort von H2CO3 zu:

statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
Macondo2Seattle
quelle
10

BEARBEITEN Die iOS 11-Methode, um herauszufinden, wo Sie den oberen Rand Ihres Ansichtsinhalts platzieren können, ist UIViews safeAreaLayoutGuideSee UIView Documentation .

VERRINGERTE ANTWORT Wenn Sie auf iOS 7+ abzielen, wird in der Dokumentation zu UIViewController empfohlen, dass die topLayoutGuideEigenschaft viewController Ihnen den unteren Rand der Statusleiste oder den unteren Rand der Navigationsleiste anzeigt, sofern diese ebenfalls sichtbar ist. Das kann von Nutzen sein und ist sicherlich weniger hack als viele der vorherigen Lösungen.

Joshua J. McKinnon
quelle
5

Vergessen Sie nicht, dass sich der Rahmen der Statusleiste im Koordinatenraum des Bildschirms befindet! Wenn Sie im Querformat starten, werden möglicherweise Breite und Höhe vertauscht. Ich empfehle dringend, stattdessen diese Version des Codes zu verwenden, wenn Sie Landschaftsorientierungen unterstützen:

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

Sie können dann die height-Eigenschaft von statusBarFrame direkt lesen. 'Ansicht' sollte in diesem Fall die Ansicht sein, in der Sie die Messungen verwenden möchten, höchstwahrscheinlich der Root-View-Controller des Anwendungsfensters.

Im Übrigen kann die Statusleiste bei Telefonanrufen nicht nur höher sein, sondern auch Null, wenn die Statusleiste absichtlich ausgeblendet wurde.

Asche
quelle
Dies gab mir nicht die richtige Höhe. Aber ich habe einen anderen Weg gefunden, der für mich funktioniert hat: stackoverflow.com/a/16598350/242933
ma11hew28
Ja, das ist jetzt ein ziemlich alter Code, daher ist er wahrscheinlich keine gültige Antwort mehr. Persönlich muss ich dank des automatischen Layouts nie mehr die Höhe der Statusleiste überprüfen.
Ash
2

Hier ist ein schneller Weg, um die Höhe der Bildschirmstatusleiste zu ermitteln:

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

Diese sind als Standardfunktion in einem meiner Projekte enthalten: https://github.com/goktugyil/EZSwiftExtensions

Esqarrouth
quelle
2

Für iOS 13 können Sie verwenden:

UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame.height
Eugene Lezov
quelle
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
    }
Bassant Ashraf
quelle
0

Ich habe gerade einen Weg gefunden, mit dem Sie nicht direkt auf die Höhe der Statusleiste zugreifen, sondern diese berechnen können.

Höhe der Navigationsleiste - topLayoutGuide-Länge = Höhe der Statusleiste

Schnell:

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

self.topLayoutGuide.lengthist der oberste Bereich, der von der durchscheinenden Leiste abgedeckt wird, und self.navigationController?.navigationBar.frame.heightist die durchscheinende Leiste ohne Statusleiste, die normalerweise 44pt beträgt. Mit dieser Methode können Sie die Höhe der Statusleiste einfach berechnen, ohne sich Gedanken über die Änderung der Statusleistenhöhe aufgrund von Telefonanrufen machen zu müssen.

Henry Ngan
quelle
Dies funktioniert nicht, self.topLayoutGuide.lengthist 0 und das Ergebnis ist -44.
Nambatee
@nambatee Ich glaube, es funktioniert nicht mehr, weil ich iOS 11 bin. Apple verwendet safeAreaInsets
Henry Ngan
0

Swift 5

UIApplication.shared.statusBarFrame.height

Haspinder Singh
quelle
-6

Mit dem folgenden einzeiligen Code können Sie die Höhe der Statusleiste in jeder Ausrichtung abrufen und auch, ob sie sichtbar ist oder nicht

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

Es ist nur ein einfaches, aber sehr nützliches Makro. Versuchen Sie es einfach. Sie müssen keinen zusätzlichen Code schreiben

Amol Hirkane
quelle