160 votes

Obtenir par programme la hauteur de la barre de navigation

Je sais que la présence du contrôleur more view (barre de navigation) fait descendre l'UIView de sa hauteur. Je sais aussi que cette hauteur = 44px. J'ai également découvert que cette poussée vers le bas maintient la valeur [self.view].frame.origin.y = 0 .

Comment puis-je déterminer la hauteur de cette barre de navigation, autrement qu'en lui attribuant une valeur constante ?

Ou, plus brièvement, comment puis-je déterminer que mon UIView s'affiche avec la barre de navigation en haut ?


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

Je crois que tout mon problème est lié à mes masques d'autoréglage. Et la raison pour laquelle j'en suis arrivé à cette conclusion est que les mêmes symptômes existent, avec ou sans UIWebView. Et ce symptôme est que tout est parfait pour le Portrait. Pour le Paysage, l'UIButton le plus bas se retrouve derrière la TabBar.

Par exemple, sur une vue UIV, j'ai, de haut en bas :

UIView - les deux ressorts sont réglés (cas par défaut) et il n'y a pas de jambes de force

UIScrollView - Si je place les deux ressorts et que j'efface tout le reste (comme l'UIView), alors l'UIButton empiète sur l'objet situé immédiatement au-dessus de lui. Si j'efface tout, l'UIButton est OK, mais l'objet situé tout en haut se cache derrière la StatusBar. En réglant uniquement l'étai supérieur, l'UIButton se retrouve derrière la Tab Bar.

UILabel et UIImage à la verticale - la jambe de force supérieure est fixée, elle est flexible partout ailleurs

Pour compléter l'image pour les quelques personnes qui ont un UIWebView :

UIWebView - Struts : top, left, right Springs : both

UIButton - rien de fixe, c'est-à-dire flexible partout

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


Soyez indulgents avec moi, car j'avais besoin de plus d'espace que celui prévu pour une brève réponse.

Merci d'avoir essayé de comprendre ce que je recherche vraiment ... alors voilà.

1) Chaque UIViewController (une application TabBar) contient une UIImage, du texte et d'autres éléments. Un autre dénominateur commun est un UIButton en bas. Sur certains des UIViewControllers, j'ai un UIWebView au-dessus de l'UIButton.

Ainsi, UIImage, texte, etc. UIWebView (sur SOME) UIButton

Tout cela est entouré d'une vue de défilement (UIScrollView).

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

   —
   |
   —

   ^
   |
   |

|-| ---- |-| | | V Le masque de l'UIButton n'est pas 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 de UIWebView, je ne fais rien d'autre que de centrer le bouton UIButton que j'ai placé avec IB.

Si j'ai un UIWebView, je détermine sa hauteur *contenu* et je définis 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 j'ai fait cela, je pousse programmatiquement l'UIButton vers le bas de sorte qu'il se retrouve placé sous le UIWebView.

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

J'appelle mes -repositionSubViews dans mon -didRotateFromInterfaceOrientation.

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

De Portrait à Paysage, la largeur du contenu doit s'étendre et la hauteur du contenu doit se réduire. Cela se passe visuellement comme il se doit, mais pas d'après mon NSLog.

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

En fin de compte, c'est la raison pour laquelle j'ai posé des questions sur la hauteur de la TabBar et de la NavigationBar, car la TabBar se place au bas de l'UIView et la NavigationBar pousse l'UIView vers le bas.

Je vais maintenant ajouter un ou deux commentaires parce qu'ils n'auraient pas eu de sens tout à l'heure.

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

Dans le cas d'un UIWebView, j'augmente la hauteur du cadre de l'UIWebView jusqu'à sa hauteur de contenu et j'ajuste également à la hausse la hauteur de l'UIScrollView qui entoure toutes les sous-vues.

Voilà qui est fait.

277voto

Sum Points 1912

Faire quelque chose comme ça ?

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

La version rapide est la suivante situé ici


MISE À JOUR

iOS 13

En tant que statusBarFrame a été supprimée dans iOS13 vous pouvez utiliser ceci :

extension UIViewController {

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

    var topbarHeight: CGFloat {
        return (view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0.0) +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
    }
}

111voto

Krunal Points 33551

Avec l'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) :

MISE À JOUR

iOS 13

En tant que statusBarFrame a été supprimée dans iOS13 vous pouvez utiliser ceci :

extension UIViewController {

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

    var topbarHeight: CGFloat {
        return (view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0.0) +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
    }
}

Objectif-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 3

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

65voto

alino-91 Points 30

Swift version :

let navigationBarHeight: CGFloat = self.navigationController!.navigationBar.frame.height

23voto

Lal Krishna Points 5552

IOS 14

Pour moi, view.window est nulle sous iOS 14.

extension UIViewController {
    var topBarHeight: CGFloat {
        var top = self.navigationController?.navigationBar.frame.height ?? 0.0
        if #available(iOS 13.0, *) {
            top += UIApplication.shared.windows.first?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
        } else {
            top += UIApplication.shared.statusBarFrame.height
        }
        return top
    }
}

17voto

Swift 5

Si vous souhaitez obtenir la hauteur de la barre de navigation, utilisez la fonction maxY qui prend également en compte la taille de la safeArea, comme ceci :

 let height = navigationController?.navigationBar.frame.maxY

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X