wake-up-neo.com

Programmgesteuert die Höhe der Navigationsleiste ermitteln

Ich weiß, dass das Vorhandensein des View-Controllers (Navigationsleiste) das UIView um seine Höhe nach unten drückt. Ich weiß auch, dass diese Höhe = 44px. Ich habe auch festgestellt, dass dieser Push-down die [self.view].frame.Origin.y = 0.

Wie bestimme ich die Höhe dieser Navigationsleiste, anstatt nur eine Konstante festzulegen?

Oder, kürzere Version, wie stelle ich fest, dass mein UIView mit der Navigationsleiste oben angezeigt wird?


Die Glühbirne ging an. Leider habe ich keine einheitliche Methode zur Behebung des Problems gefunden, wie unten beschrieben.

Ich glaube, dass sich mein ganzes Problem auf meine Autoresizing-Masken konzentriert. Und der Grund, warum ich zu dem Schluss gekommen bin, dass es die gleichen Symptome gibt, mit oder ohne UIWebView. Und dieses Symptom ist, dass für Portrait alles in Ordnung ist. Bei Landscape wird der unterste UIButton hinter der TabBar angezeigt.

Zum Beispiel habe ich auf einem UIView von oben nach unten:

UIView - beide Federn eingestellt (Standardfall) und keine Federbeine

UIScrollView - Wenn ich die zwei Federn einstelle und alles andere (wie UIView) lösche, dringt der UIButton in das Objekt unmittelbar darüber ein. Wenn ich alles lösche, ist UIButton OK, aber das Zeug ganz oben verbirgt sich hinter der Statusleiste. Wenn Sie nur die obere Strebe einstellen, wird der UIButton hinter der Registerkartenleiste eingeblendet.

UILabel und UIImage nebeneinander - Strebensatz oben, überall flexibel

Nur um das Bild für die wenigen zu vervollständigen, die über eine UIWebView verfügen:

UIWebView - Streben: oben, links, rechts Federn: beide

UIButton - nichts festgelegt, d. H. Überall flexibel

Obwohl meine Glühbirne schwach ist, scheint Hoffnung zu bestehen.


Bitte nehmen Sie Kontakt mit mir auf, da ich mehr Platz brauchte, als für eine kurze Antwort zur Verfügung stand.

Vielen Dank, dass Sie versucht haben zu verstehen, wonach ich wirklich fische.

1) Jeder UIViewController (eine TabBar-App) hat ein UIImage, Text und was auch immer oben drauf. Ein weiterer gemeinsamer Nenner ist ein UIButton am unteren Rand. Auf einigen UIViewControllern habe ich einen UIWebView über dem UIButton.

Also, UIImage, Text usw. UIWebView (auf EINEM) UIButton

Um all dies herum befindet sich ein UIScrollView.

2) Für Benutzer mit UIWebView sieht die AutoresizingMask folgendermaßen aus:

   —
   |
   —

   ^
   |
   |

| - | ← ---- → | - | | | V In der Maske des UIButton ist nichts festgelegt, d. H. Überall flexibel

In meinem -viewDidLoad rufe ich mein -repositionSubViews auf, in dem ich Folgendes mache:

Wenn es kein UIWebView gibt, kann ich nur den UIButton zentrieren, den ich mit IB platziert habe.

Wenn ich ein UIWebView habe, bestimme ich dessen * Inhalt * Höhe und setze seinen Rahmen so, dass er den gesamten Inhalt einschließt.

UIScrollView *scrollViewInsideWebView = [[webView_ subviews] lastObject];
webViewContentHeight = scrollViewInsideWebView.contentSize.height;
[webView_ setFrame:CGRectMake(webViewOriginX, webViewOriginY,
                          sameWholeViewScrollerWidth, webViewContentHeight)]

Sobald ich das getan habe, drücke ich den UIButton programmatisch nach unten, so dass er sich unterhalb des UIWebView befindet.

Alles funktioniert, bis ich es von Hochformat zu Querformat drehe.

Ich rufe meine -repositionSubViews in meiner -didRotateFromInterfaceOrientation auf.

Warum ändert sich die Inhaltshöhe meines UIWebView nicht mit der Drehung?.

Von Hochformat zu Querformat sollte die Inhaltsbreite vergrößert und die Inhaltshöhe verkleinert werden. Es macht optisch, wie es sollte, aber nicht nach meinem NSLog.

Egal, mit oder ohne UIWebView, die Schaltfläche, über die ich gesprochen habe, wird im Querformat unter der TabBar verschoben, aber sie wird nicht nach oben gescrollt, um angezeigt zu werden. Ich sehe es hinter der TabBar, wenn ich "heftig" scrolle, aber dann "fällt" es hinter der TabBar zurück.

Unterm Strich ist dies der Grund, warum ich nach der Höhe der TabBar und der NavigationBar gefragt habe, da die TabBar sich am unteren Rand der UIView anordnet und die NavigationBar die UIView nach unten drückt.

Jetzt werde ich hier ein oder zwei Kommentare hinzufügen, weil sie früher keinen Sinn ergeben hätten.

Ohne UIWebView lasse ich alles so, wie es von IB gesehen wird.

Mit einer UIWebView erhöhe ich die frame.height der UIWebView auf contentHeight und passe die Höhe der umgebenden UIScrollView, die alle Unteransichten umgibt, nach oben an.

Na da hast du es.

116
John Love

Die Glühbirne ging an. Leider habe ich keine einheitliche Methode zur Behebung des Problems gefunden, wie unten beschrieben.

Ich glaube, dass sich mein ganzes Problem auf meine Autoresizing-Masken konzentriert. Und der Grund, warum ich zu dem Schluss gekommen bin, dass es die gleichen Symptome gibt, mit oder ohne UIWebView. Und dieses Symptom ist, dass für Portrait alles in Ordnung ist. Bei Landscape wird der unterste UIButton hinter der TabBar angezeigt.

Zum Beispiel habe ich auf einem UIView von oben nach unten:

IView - beide Federn eingestellt (Standardfall) und keine Federbeine

IScrollView - Wenn ich die zwei Federn einstelle und alles andere (wie das UIView) lösche, dringt der UIButton in das Objekt unmittelbar darüber ein. Wenn ich alles lösche, ist UIButton OK, aber das Zeug ganz oben verbirgt sich hinter der Statusleiste. Wenn Sie nur die obere Strebe einstellen, wird der UIButton hinter der Registerkartenleiste eingeblendet.

ILabel und UIImage nächster vertikaler Strebensatz, überall flexibel

Nur um das Bild für die wenigen zu vervollständigen, die über eine UIWebView verfügen:

IWebView - Federbeine: oben, links, rechts Federbeine: beide

IButton - nichts gesetzt, d. H. Überall flexibel

Obwohl meine Glühbirne schwach ist, scheint Hoffnung zu bestehen.

1
John Love

Mach so etwas?

    NSLog(@"Navframe Height=%f",
        self.navigationController.navigationBar.frame.size.height);

Die Swift Version ist befindet sich hier

238
Sum

Mit dem iPhone-X wird die Höhe der oberen Leiste (Navigationsleiste + Statusleiste) geändert (erhöht).

Versuchen Sie dies, wenn Sie die exakte Höhe der oberen Leiste wünschen (sowohl Navigationsleiste als auch Statusleiste):

Ziel-C

CGFloat topbarHeight = ([UIApplication sharedApplication].statusBarFrame.size.height +
       (self.navigationController.navigationBar.frame.size.height ?: 0.0));

Swift 4

let topBarHeight = UIApplication.shared.statusBarFrame.size.height +
        (self.navigationController?.navigationBar.frame.height ?? 0.0)

Probieren Sie zur Vereinfachung diese UIViewController-Erweiterung aus

extension UIViewController {

    /**
     *  Height of status bar + navigation bar (if navigation bar exist)
     */

    var topbarHeight: CGFloat {
        return UIApplication.shared.statusBarFrame.size.height +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
    }
}

Swift

let topBarHeight = UIApplication.sharedApplication().statusBarFrame.size.height +
(self.navigationController?.navigationBar.frame.height ?? 0.0)
66
Krunal

Swift Version:

let navigationBarHeight: CGFloat = self.navigationController!.navigationBar.frame.height
57
King-Wizard

Hast du das probiert?

let barHeight = self.navigationController?.navigationBar.frame.height ?? 0
6
Keaz
UIImage*image = [UIImage imageNamed:@"logo"];

float targetHeight = self.navigationController.navigationBar.frame.size.height;
float logoRatio = image.size.width / image.size.height;
float targetWidth = targetHeight * logoRatio;

UIImageView*logoView = [[UIImageView alloc] initWithImage:image];
// X or Y position can not be manipulated because autolayout handles positions.
//[logoView setFrame:CGRectMake((self.navigationController.navigationBar.frame.size.width - targetWidth) / 2 , (self.navigationController.navigationBar.frame.size.height - targetHeight) / 2 , targetWidth, targetHeight)];
[logoView setFrame:CGRectMake(0, 0, targetWidth, targetHeight)];
self.navigationItem.titleView = logoView;

// How much you pull out the strings and struts, with autolayout, your image will fill the width on navigation bar. So setting only height and content mode is enough/
[logoView setContentMode:UIViewContentModeScaleAspectFit];

/* Autolayout constraints also can not be manipulated since navigation bar has  immutable constraints
self.navigationItem.titleView.translatesAutoresizingMaskIntoConstraints = false;

NSDictionary*metricsArray = @{@"width":[NSNumber numberWithFloat:targetWidth],@"height":[NSNumber numberWithFloat:targetHeight],@"margin":[NSNumber numberWithFloat:20]};
NSDictionary*viewsArray = @{@"titleView":self.navigationItem.titleView};

[self.navigationItem.titleView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-(>margin=)-H:[titleView(width)]-(>margin=)-|" options:NSLayoutFormatAlignAllCenterX metrics:metricsArray views:viewsArray]];
[self.navigationItem.titleView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[titleView(height)]" options:0 metrics:metricsArray views:viewsArray]];

NSLog(@"%f", self.navigationItem.titleView.width );
*/

Also brauchen wir eigentlich nur

UIImage*image = [UIImage imageNamed:@"logo"];
UIImageView*logoView = [[UIImageView alloc] initWithImage:image];
float targetHeight = self.navigationController.navigationBar.frame.size.height;
[logoView setFrame:CGRectMake(0, 0, 0, targetHeight)];
[logoView setContentMode:UIViewContentModeScaleAspectFit];

self.navigationItem.titleView = logoView;
4
ironik sütlaç

Meine Anwendung verfügt über einige Ansichten, für die eine angepasste Navigationsleiste in der Benutzeroberfläche erforderlich ist, jedoch ohne Navigationscontroller. Die Anwendung muss die iOS-Version vor iOS 11 unterstützen, sodass der praktische Leitfaden für das Layout sicherer Bereiche nicht verwendet werden konnte und ich Position und Höhe der Navigationsleiste programmgesteuert anpassen muss.

Ich habe die Navigationsleiste direkt an die Übersicht angehängt und dabei die oben erwähnte Anleitung zum Layout des sicheren Bereichs übersprungen. Und die Höhe der Statusleiste kann leicht aus UIApplication abgerufen werden, aber die Standardhöhe der Navigationsleiste ist wirklich ein ...

Es hat mich fast eine halbe Nacht lang beeindruckt, mit einer Reihe von Suchen und Tests, bis ich schließlich den Hinweis von einem anderen Post bekam (der mir allerdings nicht geholfen hat), dass Sie tatsächlich die Höhe von UIView.sizeThatFits () erhalten könnten :

- (void)viewWillLayoutSubviews {
    self.topBarHeightConstraint.constant = [UIApplication sharedApplication].statusBarFrame.size.height;
    self.navBarHeightConstraint.constant = [self.navigationBar sizeThatFits:CGSizeZero].height;

    [super viewWillLayoutSubviews];    
}

Endlich eine perfekte Navigationsleiste, die genauso aussieht wie die eingebaute!

2
Stephen Liu

Hier ist der Beginn meiner Antwort auf Ihr Update:

Warum ändert sich die Inhaltshöhe meines UIWebView nicht mit der Drehung?.

Könnte es sein, dass Ihre automatische Größenänderung nicht die autoresizingMask für alle Richtungen hat?

Noch ein Vorschlag, bevor ich darauf zurückkomme, könnten Sie eine Symbolleiste für Ihre Bedürfnisse verwenden. Es ist ein bisschen einfacher, wird immer auf der Unterseite sein, dreht sich automatisch/Positionen. Sie können es nach Belieben ein- und ausblenden. In etwa so: app-2.jpg

Vielleicht haben Sie sich diese Option angeschaut, aber sie einfach da rausgeworfen.

Eine andere Idee ist, dass Sie möglicherweise erkennen, aus welcher Ausrichtung Sie drehen, und die Schaltfläche programmgesteuert platzieren, um sie an die Registerkartenleiste anzupassen. (Dies ist mit Code möglich)

1
Sum

Ich habe benutzt:

let originY: CGFloat = self.navigationController!.navigationBar.frame.maxY

Funktioniert hervorragend, wenn Sie die Höhe der Navigationsleiste UND deren Y-Ursprung abrufen möchten.

0
user3332228

Handy Swift 4 Erweiterung, falls es jemand anderem hilft.

import UIKit

extension UINavigationController {
  static public func navBarHeight() -> CGFloat {
    let nVc = UINavigationController(rootViewController: UIViewController(nibName: nil, bundle: nil))
    let navBarHeight = nVc.navigationBar.frame.size.height
    return navBarHeight
  }
}

Verwendung:

UINavigationController.navBarHeight()
0
CodenameDuchess