Je souhaite utiliser une UINavigationBar
personnalisée dans l'une de mes vues, qui ne fait partie d'aucune hiérarchie UINavigationController
. Lorsque je traîne un UINavigationBar
dans Storyboard, il se présente comme suit:
Cette barre fait 44 pixels, ce qui serait suffisant si la barre d'état ne partageait pas cet espace. Étant donné qu'iOS7 nous permet d'utiliser la totalité de l'écran, y compris l'espace pour la barre d'état, le UINavigationBar
devrait avoir une hauteur de 64px et non de 44px.
Si je connecte la vue à une hiérarchie de UINavigationController
, elle indique alors correctement:
J'ai lu quelque part que si le UINavigationBar
a la propriété barPosition:
réglé sur UIBarPositionTopAttached
, la barre serait alors 64px. Ceci est cependant une propriété readonly
-.
Mes résultats de recherche ont seulement montré quelque chose que je considère comme une solution de rechange. En ajoutant un UINavigationController
inutile avant ce UIViewController
, je peux prétendre avoir une hiérarchie et il ajoutera automatiquement le UINavigationBar
avec 64px.
Existe-t-il vraiment aucun moyen d'avoir un 'voyou' (sans l'aide d'un contrôleur de navigation) UINavigationBar
couvrant 64px? Si tel est le cas, y a-t-il des raisons valables pour lesquelles?
(Je ne dis pas que le UINavigationBar
devrait être de 64 pixels par défaut, mais il devrait y avoir une option pour cela dans l'inspecteur)
(Je vois aussi des gens qui répondent par des moyens programmatiques pour résoudre ce problème. Même si ces réponses fonctionnent, je devrais tout de même concevoir le scénarimage en gardant cela à l'esprit. (un écart). Ce que je veux savoir, c'est s'il est possible de définir cela dans le scénarimage, ou plutôt, pourquoi n'est-il pas permis?)
Vous pouvez définir la propriété barPosition
sur UIBarPositionTopAttached
d'une autre manière!
Mettre en place -positionForBar:
dans la classe des délégués:
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
{
return UIBarPositionTopAttached;
}
Le haut de votre barre de navigation doit également être ancré dans le Guide de disposition supérieure.
Vous pouvez modifier la hauteur de la barre de navigation par programmation:
[navBar setFrame:CGRectMake(0, 0, 320, 64)];
Edit: Comme je l’ai écrit dans les commentaires, vous devrez peut-être mettre cette ligne dans viewDidLayoutSubviews
pour contourner le autolayout.
Vous pouvez le configurer pour qu'il s'attache en haut de la vue en utilisant les "Attributs d'exécution définis par l'utilisateur" dans "Inspecteur d'identité" dans Interface Builder. Définissez la propriété barPosition
.
Voici la documentation pour la propriété barPosition
: https://developer.Apple.com/library/ios/documentation/uikit/reference/UIBarPositioning_Protocol/Reference/Reference.html
Il existe un moyen d'accomplir ceci SANS utiliser un UINavigationController
ou le définir par programme. Il suffit de définir une contrainte de hauteur sur la barre de navigation sur ce que vous voulez, 64 dans ce cas.
Vous pouvez accomplir la même chose par programme en tant que tel:
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:navigationBar attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1 constant:64.0f]];
MODIFIER:
Comme @ nerdist-colony l'a souligné, lorsque vous utilisez Autolayout, il a toujours été de définir translatesAutoresizingMaskIntoConstraints
sur NO
, sinon il pourrait y avoir des conflits de contraintes.
J'utilise également une barre UINavigationBar autonome et j'ai rencontré le même problème. J'ai découvert qu'il existe deux manières de résoudre ce problème correctement.
Je l'ai corrigé en utilisant des contraintes et un parent UIView. J'ai défini cette UIView dans le storyboard en tant que vue parent de ma UINavigationBar avec une image {0, 0, 320, 64}. Vous pouvez ajouter une contrainte ou un ensemble de contraintes forçant UINavigationBar à avoir la taille souhaitée. Et étant donné que votre parent UIView a la bonne image dans votre story-board, vous pouvez mettre en page vos autres vues habituelles dans votre story-board.
Désormais, si l'autolayout est désactivé, vous pouvez modifier la hauteur de la barre par programmation, comme indiqué dans la réponse de Lindsey. -(void)viewDidLayoutSubviews
semble être un bon endroit pour le faire.
Si vous utilisez Autolayout, vous pouvez définir la contrainte de hauteur de UINavigationBar sur 64 ou plus.
Dans Swift 3 en utilisant le storyboard principal, vous pouvez utiliser des contraintes pour modifier la hauteur et la faire fonctionner. C’est ainsi que j’ai trouvé que c’était facile à mettre en œuvre.
J'ai écrit un article de blog expliquant comment procéder avec une intervention minimale du code. Votre barre indiquera un vide dans le story-board, mais cela fonctionnera correctement sur l'appareil. En bref, les étapes sont les suivantes:
1) Ajoutez la barre de navigation au contrôleur de vue dans le storyboard.
2) Définissez les contraintes pour la barre de navigation dans le storyboard:
- Barre de navigation.Top = Top Layout Guide.Bottom
- Barre de navigation.Leading = Superview.Leading
- Barre de navigation.Trailing = Superview.Trailing
3) Connectez la barre de navigation du storyboard à son contrôleur de vue en tant que @IBOutlet.
4) Dans la classe du contrôleur de vue, ajoutez un protocole UINavigationBarDelegate à la déclaration de classe.
5) Dans la méthode viewDidLoad du contrôleur de vue, définissez le délégué de la barre de navigation sur self.
6) Dans le contrôleur de vue, ajoutez la méthode positionForBar du délégué de positionnement de la barre. Renvoie la propriété UIBarPosition représentant TopAttached. (Remarque: UINavigationBarDelegate hérite de cette méthode d'UIBarPositioningDelegate.)
Le post complet avec des images GIF est ici:
tilisez facilement une barre de navigation sans contrôleur de navigation correspondant
Ces étapes fonctionnent à partir de Swift 2.1/Xcode 7.2
@startupThekid:
iOS générera une exception si vous essayez de modifier le masque de redimensionnement automatique pour un UINavigationBar géré par un UINavigationController.
Cependant, l'équivalent Swift du code Objective C que vous avez publié est:
var navBar = self.navigationController!.navigationBar
dans viewDidAppear ():
navBar.setTranslatesAutoresizingMaskIntoConstraints = false
Où que vous deviez définir la contrainte:
var navBarHeightConstraint =
NSLayoutConstraint(item: navBar, attribute: .Height,
relatedBy: .Equal, toItem: nil,
attribute: .Height, multiplier: 1, constant: height)
self.view.addConstraint(navBarHeightConstraint)
Ensuite, vous devriez pouvoir modifier la propriété constante de la contrainte de manière à modifier la hauteur de la barre de navigation, par exemple pour modifier l'orientation de l'appareil .
J'étais dans le même bateau et j'avais des problèmes, mais maintenant je l'ai corrigé. J'essaie de prendre les mesures qui s'imposent pour éviter de définir le cadre de manière explicite, ce qui est souhaitable pour assurer la pérennité et faciliter la prise en charge de différentes tailles d'appareils. Dans mon cas, je veux une vue Web sous une barre de navigation.
Je règle mon contrôleur de vue sur UINavigationBarDelegate
et implémente positionForBar:
pour retourner UIBarPositionTopAttached
, comme réponse de l'utilisateur326971 . Il semblait que l’autre astuce consistait à utiliser la disposition automatique pour positionner la barre sous le topLayoutGuide.
Ceci était le code que j'utilisais dans viewDidLoad
après avoir créé la barre de navigation et la vue Web par programme, et je voyais toujours la barre bloquée en hauteur. 44 mais ne pouvait pas voir immédiatement pourquoi:
[navigationBar sizeToFit];
navigationBar.delegate = self;
[self.view addSubview:navigationBar];
[self.view addSubview:webView];
id guide = self.topLayoutGuide;
NSDictionary *viewNamesDict = NSDictionaryOfVariableBindings(webView, navigationBar, guide);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[webView]|" options:0 metrics:nil views:viewNamesDict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[guide][navigationBar][webView]|" options:0 metrics:nil views:viewNamesDict]];
Mais j’ai réfléchi un peu plus et joué avec la mise en page automatique, et il s’avère que c’est la seule cause de mon problème. J'essayais de m'appuyer sur les contraintes traduites de la barre de navigation à partir de son masque de redimensionnement automatique, mais il s'est avéré que je devais les définir explicitement. Voici mon nouveau code viewDidLoad
qui fonctionne:
[navigationBar sizeToFit];
navigationBar.delegate = self;
navigationBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:navigationBar];
[self.view addSubview:webView];
id guide = self.topLayoutGuide;
NSDictionary *viewNamesDict = NSDictionaryOfVariableBindings(webView, navigationBar, guide);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[navigationBar]|" options:0 metrics:nil views:viewNamesDict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[webView]|" options:0 metrics:nil views:viewNamesDict]];
NSString *verticalLayoutVisualExpression = [NSString stringWithFormat:@"V:|[guide][navigationBar(%f)][webView]|", navigationBar.frame.size.height];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:verticalLayoutVisualExpression options:0 metrics:nil views:viewNamesDict]];
Et oui, comme je l'espérais, cela déplace automatiquement la barre lorsque vous passez en mode Paysage et que la barre d'état se cache.
(Je recommande vivement un assistant de mise en page automatique tel que Maçonnerie qui rend le code de mise en page plus concis, et Maçonnerie, par exemple, s'occupe de désactiver translatesAutoresizingMaskIntoConstraints
pour vous)
Je sais que c’est une façon très déconcertante de faire cela, mais pour moi cela a fonctionné. J'ai un NavigationViewController
et je veux charger un ViewController modalement qui a un UINavigationBar
en haut avec les boutons Terminé et Annuler. Voici à quoi cela ressemblait:
Comme vous pouvez le voir, il y a une bande blanche en haut que je veux avoir la même couleur que le UINavigationBar
. Au lieu de modifier la hauteur de UINavigationBar
par programme, je viens de créer une nouvelle vue et de définir sa couleur d'arrière-plan égale à celle de UINavigationBar
(HEX = F8F8F8, RGBA = 248,248,248,1.0). Encore une fois, je sais que c’est super, mais cela me permet de faire le travail. Voici à quoi ça ressemble maintenant