web-dev-qa-db-fra.com

Obtenir la hauteur de la barre de navigation par programme

Je sais que la présence du contrôleur de vue supplémentaire (barre de navigation) abaisse UIView par sa hauteur. Je sais aussi que cette hauteur = 44px. J'ai aussi découvert que cette pression maintenait le [self.view].frame.Origin.y = 0.

Alors, comment puis-je déterminer la hauteur de cette barre de navigation, mis à part le fait de la définir comme constante?

Ou, version plus courte, comment puis-je déterminer que mon UIView est affiché avec la barre de navigation en haut?


L'ampoule a commencé à s'allumer. Malheureusement, je n'ai pas trouvé de solution uniforme au problème, comme décrit ci-dessous.

Je crois que tout mon problème est centré sur mon auto-dimensionnement des masques. Et la raison pour laquelle j'ai conclu que les mêmes symptômes existaient, avec ou sans UIWebView. Et ce symptôme est que tout est pêche pour Portrait. Pour Landscape, le dernier UIButton apparaît derrière le TabBar.

Par exemple, sur un UIView, j'ai, de haut en bas:

UIView - ensemble de ressorts (cas par défaut) et pas d'entretoise

UIScrollView - Si je règle les deux ressorts et efface tout le reste (comme UIView), l'UIButton s'introduit dans l'objet situé immédiatement au-dessus de celui-ci. Si je supprime tout, alors UIButton est OK, mais tout ce qui se trouve tout en haut se cache derrière la StatusBar. En définissant uniquement la jambe supérieure, l'UIButton apparaît derrière la barre d'onglets.

UILabel et UIImage ensuite à la verticale - jeu de jambes de force supérieur, flexible partout ailleurs

Juste pour compléter le tableau pour les rares qui ont un UIWebView:

UIWebView - Struts: haut, gauche, droite Ressorts: les deux

UIButton - rien n'est défini, c’est-à-dire qu’il est flexible partout

Bien que mon ampoule soit faible, il semble y avoir de l'espoir.


S'il vous plaît supporter avec moi parce que j'avais besoin de plus d'espace que celui prévu pour un bref commentaire de réponse.

Merci d'avoir essayé de comprendre ce pour quoi je pêche vraiment ... alors voilà.

1) Chaque UIViewController (une application TabBar) a un UIImage, du texte et ainsi de suite. Un autre dénominateur commun est un UIButton sur le fond. Sur certains UIViewControllers, j'ai un UIWebView au-dessus du UIButton.

Donc, UIImage, texte, etc. UIWebView (sur certains) UIButton

UIScrollView est entouré de tout ce qui précède.

2) Pour ceux qui ont un UIWebView, son autoresizingMask ressemble à:

   —
   |
   —

   ^
   |
   |

| - | ← ---- → | - | | | V Le masque d’UIButton n’a rien de défini, c’est-à-dire qu’il est flexible partout

Dans mon -viewDidLoad, j'appelle mon -repositionSubViews dans lequel je fais ce qui suit:

S'il n'y a pas d'UIWebView, je ne fais rien sauf centrer le UIButton que j'ai placé avec IB.

Si j'ai un UIWebView, alors je détermine sa hauteur * content * et configure son cadre pour qu'il englobe tout le contenu.

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

Une fois que je fais cela, alors je programme par programme Poussez le bouton UIB vers le bas afin qu’il finisse par être placé en dessous de UIWebView.

Tout fonctionne, jusqu'à ce que je le fasse pivoter de Portrait en Paysage.

J'appelle mon -repositionSubViews dans mon -didRotateFromInterfaceOrientation.

Pourquoi la hauteur du contenu de mon UIWebView ne change-t-elle pas avec la rotation?.

De Portrait en Paysage, la largeur du contenu doit s’étendre et sa hauteur doit être réduite. Il fonctionne visuellement comme il se doit, mais pas selon mon NSLog.

Quoi qu'il en soit, avec ou sans UIWebView, le bouton dont j'ai parlé se déplace en dessous du TabBar en mode Paysage, mais il ne défilera pas pour être vu. Je le vois derrière le TabBar lorsque je fais défiler "vigoureusement", mais ensuite il "retombe" derrière le TabBar.

En bout de ligne, ce dernier point est la raison pour laquelle j'ai posé des questions sur la hauteur de la barre de contrôle et de la barre de navigation, car cette dernière se positionne au bas de la vue UIV et que la barre de navigation abaisse la vue UIV.

Maintenant, je vais ajouter un ou deux commentaires ici parce qu'ils n'auraient pas eu de sens plus tôt.

Sans UIWebView, je laisse tout tel que vu par IB.

Avec UIWebView, j'augmente le frame.height de UIWebView à son contentHeight et ajuste également vers le haut la hauteur de UIScrollView qui entoure toutes les sous-vues.

Bien, tu l'as maintenant.

116
John Love

L'ampoule a commencé à s'allumer. Malheureusement, je n'ai pas trouvé de solution uniforme au problème, comme décrit ci-dessous.

Je crois que tout mon problème est centré sur mon auto-dimensionnement des masques. Et la raison pour laquelle j'ai conclu que les mêmes symptômes existaient, avec ou sans UIWebView. Et ce symptôme est que tout est pêche pour Portrait. Pour Landscape, le dernier UIButton apparaît derrière le TabBar.

Par exemple, sur un UIView, j'ai, de haut en bas:

IView - les deux ressorts sont définis (cas par défaut) et aucun amortisseur

IScrollView - Si je règle les deux ressorts et efface tout le reste (comme UIView), l'UIButton envahit l'objet situé immédiatement au-dessus de celui-ci. Si je supprime tout, alors UIButton est OK, mais tout ce qui se trouve tout en haut se cache derrière la StatusBar. En définissant uniquement la jambe supérieure, l'UIButton apparaît derrière la barre d'onglets.

ILabel et UIImage next verticalement - jeu de jambes de force supérieur, flexible partout ailleurs

Juste pour compléter le tableau pour les rares qui ont un UIWebView:

IWebView - Jambes de force: haut, gauche, droite Ressorts: les deux

IButton - rien n'est défini, c’est-à-dire flexible partout

Bien que mon ampoule soit faible, il semble y avoir de l'espoir.

1
John Love

Faire quelque chose comme ça?

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

La version Swift est située ici

238
Sum

Avec iPhone-X, la hauteur de la barre supérieure (barre de navigation + barre d'état) est modifiée (augmentée).

Essayez ceci si vous voulez la hauteur exacte de la barre supérieure (barre de navigation + barre d’état):

Objective-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)

Pour plus de facilité, essayez cette extension UIViewController

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

Avez-vous essayé cela?

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 );
*/

Donc tout ce dont nous avons besoin est

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ç

Mon application présente plusieurs vues nécessitant une barre de navigation personnalisée dans l'interface utilisateur pour l'aspect et la convivialité, mais sans contrôleur de navigation. Et comme l'application est requise pour prendre en charge la version iOS antérieure à iOS 11, le guide pratique de présentation de la zone sécurisée ne peut pas être utilisé et je dois ajuster la position et la hauteur de la barre de navigation par programme.

J'ai attaché la barre de navigation à sa vue d'ensemble directement, en sautant le guide de disposition de la zone de sécurité, comme mentionné ci-dessus. Et la hauteur de la barre d'état pourrait être récupérée facilement depuis UIApplication, mais la hauteur par défaut de la barre de navigation est vraiment pénible ...

Cela m'a frappé pendant presque une demi-nuit, avec un certain nombre de recherches et de tests, jusqu'à ce que je reçoive enfin l'allusion d'un autre message (qui ne fonctionne pas pour moi cependant), que vous pourriez réellement obtenir la hauteur de UIView.sizeThatFits (), comme ceci :

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

    [super viewWillLayoutSubviews];    
}

Enfin, une barre de navigation parfaite ayant exactement la même apparence que celle intégrée!

2
Stephen Liu

Voici le début de ma réponse à votre mise à jour:

Pourquoi la hauteur du contenu de mon UIWebView ne change-t-elle pas avec la rotation?.

Se pourrait-il que parce que votre redimensionnement automatique ne dispose pas du masque autoresizing pour toutes les directions?

Une autre suggestion avant que je revienne pour cela, pourriez-vous utiliser une barre d’outils pour vos besoins. C'est un peu plus simple, on sera toujours en bas, les rotations/positions automatiques. Vous pouvez cacher/afficher à volonté, etc. Un peu comme ceci: http://cdn.artoftheiphone.com/wp-content/uploads/2009/01/yellow-pages-iphone-app-2.jpg

Vous avez peut-être envisagé cette option, mais vous l'avez simplement lancée.

Une autre idée: pouvez-vous éventuellement détecter l’orientation à partir de laquelle vous faites pivoter et placez simplement le bouton par programmation pour ajuster la barre de tabulation. (Ceci est possible avec le code)

1
Sum

J'ai utilisé:

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

Fonctionne très bien si vous voulez obtenir la hauteur de la barre de navigation ET son origine Y.

0
user3332228

Handy Swift 4 extension, au cas où cela serait utile à quelqu'un d'autre.

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
  }
}

Usage:

UINavigationController.navBarHeight()
0
CodenameDuchess