Dans mon application, un contrôleur de vue est doté d'une barre de navigation qui est glissée dans le story-board. Cela fonctionnait bien sous iOS 6, mais sous iOS 7, il se présentait ainsi:
La barre d'état et la barre de navigation ne doivent pas entrer en collision. J'ai vu beaucoup de telles questions sur le débordement de pile, mais elles ne m'ont pas beaucoup aidé.
Certaines questions disent que je devrais utiliser ce "self.edgesForExtendedLayout = UIRectEdgeNone;" mais ça n'a pas marché. Certains disent que je devrais supprimer la barre de navigation et l'intégrer dans le contrôleur de navigation, ce que je ne peux pas faire en raison de la manière dont mon programme est mis en œuvre. Certaines solutions suggèrent d'utiliser les limites de la vue et tout, mais cela n'a pas fonctionné pour moi aussi.
Quelle est la seule chose qui peut m'aider à résoudre ce problème? Merci d'avance!
UPDATE: J'ai intégré le contrôleur de vue à l'intérieur d'un contrôleur d'uravigation. Suppression de la barre de navigation précédemment ajoutée manuellement. Maintenant, ça a l'air correct dans le storyboard, mais quand je le lance, il montre ce qui suit:
Il montre le texte d'un autre contrôleur de vue qui se trouve actuellement derrière son contrôleur de vue parent. Signifie sa transparence maintenant. Quelqu'un peut-il signaler ce que je fais mal?
La dernière version de l'iOS a apporté de nombreux changements visuels et, du point de vue du développeur, la barre de navigation et la barre d'état sont deux changements notables.
La barre d'état est maintenant transparente et la barre de navigation derrière elle est visible. L'image de la barre de navigation peut même être étendue derrière la barre d'état.
Tout d’abord, si vous êtes débutant et que vous venez de commencer le développement sur iOS et que vous ne comprenez pas comment la barre d’état et la barre de navigation fonctionnent, vous pouvez simplement passer par un article de blog ICI que j’ai trouvé très utile. Il contient toutes les informations relatives à la navigation et à la barre d'état dans iOS 7.
J'en viens maintenant à la réponse à votre question. Tout d'abord, je peux voir deux problèmes différents. La première est que votre barre d’état et votre barre de navigation sont toutes deux en collision, comme vous l’indiquez dans la question avec une image.
PROBLEME: Le problème est que vous avez déjà fait glisser une barre de navigation dans votre contrôleur de vue qui fonctionnait correctement sous iOS 6, mais avec l'arrivée du SDK iOS 7, cette approche entraîne le chevauchement de la barre d'état et de la barre de navigation. L'un et l'autre.
SOLUTION au premier problème: Vous pouvez utiliser UIBarPositionTopAttached ou des limites de vue et des cadres, je peux également vous suggérer et vous lier à à la documentation Apple et à bla bla mais cela prendrait un certain temps résoudre le problème.
Le moyen le plus simple et le plus simple de résoudre ce problème consiste simplement à intégrer votre contrôleur de vue dans un contrôleur de navigation et c'est tout. Vous pouvez le faire en sélectionnant simplement le contrôleur de vue et en sélectionnant Editeur> Intégrer dans> Contrôleur de navigation. (S'il y a du contenu sur votre ancienne barre de navigation, vous pouvez d'abord le faire glisser vers le bas, incorporer le contrôleur de vue dans le contrôleur de navigation, puis déplacer les boutons de la barre sur la nouvelle barre de navigation, puis supprimer l'ancienne barre de navigation.)
SOLUTION au deuxième problème: Cette solution concerne votre question spécifique que vous avez mentionnée dans la mise à jour et n'est pas destinée au grand public. Comme vous pouvez le constater, la barre de navigation et la barre d'état ne sont pas visibles et une zone transparente affiche le contrôleur de vue parent. Je ne comprends pas vraiment pourquoi vous faites face à ce problème, mais très probablement à cause de la présence d’une bibliothèque tierce telle que ECSlidingView ou toute autre. Vous pouvez sélectionner ce contrôleur de vue dans votre story-board et définir la couleur d'arrière-plan de la vue sur celle de votre barre de navigation. Cela arrêtera d'afficher le contrôleur de vue parent derrière et votre barre de navigation et votre barre d'état commenceront à s'afficher. Maintenant, vous pouvez couvrir le reste de votre contrôleur de vue avec la vue texte ou tout ce que vous y utilisez.
J'espère que cela t'aides!
La barre de navigation est trop proche de la barre d'état car à partir de iOS 7, la barre d'état est davantage une superposition sur la vue de l'ensemble du contrôleur de vue. Puisque votre barre de navigation est à (0, 0), la barre d’état s’affiche en haut de la barre de navigation. Pour résoudre ce problème, déplacez simplement la barre de navigation vers le bas (ou, comme d'autres l'ont dit), créez une contrainte entre la barre de navigation et topLayoutGuide.
Ce faisant, vous constaterez qu’il ya maintenant un écart de 20 points entre la barre de navigation et le haut de l’écran. C'est parce que vous venez de déplacer la barre de navigation de 20 points. "Mais UINavigationController
peut le faire correctement!" Absolument, et cela en implémentant UIBarPositioningDelegate
sur votre contrôleur de vue. C'est un protocole à une méthode qui devrait être implémenté comme ceci:
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar {
return UIBarPositionTopAttached;
}
Après avoir ajouté votre contrôleur de vue en tant que délégué pour la barre de navigation, vous remarquerez que la barre de navigation est toujours décalée de 20 points, mais son arrière-plan s'étendra sous la barre d'état, comme dans UINavigationController
.
Une autre chose que vous constatez est que la barre de navigation est translucide, ce qui signifie que tout ce qui se trouve sous la barre de navigation sera visible dans une certaine mesure. La propriété translucent
sur UINavigationBar
est définie sur YES
par défaut sur iOS 7. Avant iOS 7, la valeur par défaut était NO
.
vous pouvez simplement faire ceci:
1) ajoutez une contrainte entre la barre de navigation et le guide de disposition supérieur (sélectionnez navigationBar, maintenez la touche ctrl enfoncée et accédez à Guide de mise en forme inférieur, retirez la touche ctrl)
2) sélectionnez espacement vertical:
3) régler constante sur 0:
Résultat:
METTRE &AGRAVE; JOUR
Dans votre fichier AppDelegate, vous pouvez ajouter ceci:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
// Prevent Navigationbar to cover the view
UINavigationBar.appearance().translucent = false
}
Je vous suggère dans votre méthode viewDidLoad d'essayer:
self.navigationController.navigationBar.translucent = NO;
(par défaut c'est oui maintenant)
Si votre UIViewController
N'EST PAS dans une UINavigationController
et que vous utilisez UIStoryBoard
, vous pouvez définir "iOS 6/7 Deltas" sur 20 pour le delta Y, pour chaque sous-vue devant être décalée par rapport à la UIStatusBar
.
Utilisation de Swift :
Comme @Scott Berrevoets l'a dit dans sa réponse, vous devez implémenter la méthode positionForBar
dans le protocole UIBarPositioningDelegate
, mais comme le protocole UINavigationBarDelegate
implémente ce protocole:
public protocol UINavigationBarDelegate : UIBarPositioningDelegate {
...
}
Il vous suffit de définir la variable delegate
de la variable UINavigationBar
que vous avez définie à l'aide de Storyboard et d'implémenter la méthode et c'est fait, comme suit:
class ViewController: UIViewController, UINavigationBarDelegate {
@IBOutlet weak var navigationBar: UINavigationBar!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationBar.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func positionForBar(bar: UIBarPositioning) -> UIBarPosition {
return UIBarPosition.TopAttached
}
}
NOTE: Il vaut la peine de mentionner que si vous définissez la position de l'axe y de la barre de navigation, disons à 40 à partir du haut, elle s'étendra ensuite de bas en haut position, pour simuler le comportement de la UINavigationController
, vous devez lui attribuer la valeur 20 à partir du haut.
J'espère que cela vous aidera.
Cela fonctionne pour moi j'espère que vous avez aussi la même chance:) .
Ajoutez le code ci-dessous dans votre vue.
-(void) viewDidLayoutSubviews
{
CGRect tmpFram = self.navigationController.navigationBar.frame;
tmpFram.Origin.y += 20;
self.navigationController.navigationBar.frame = tmpFram;
}
Il change fondamentalement l'emplacement de la barre de navigation.
Si cela aide toujours quelqu'un, voici ce qui a fonctionné pour moi pour déplacer légèrement la barre de navigation dans iOS 7 et versions supérieures:
-(void)viewWillLayoutSubviews
{
float iosVersion = 7.0;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= iosVersion) {
// iOS 7+
CGRect viewFrame = self.view.frame;
viewFrame.Origin.y += 10;
self.view.frame = viewFrame;
}
}
Sur un appareil avec ios 6.1 et inférieur, la barre de navigation reste inchangée, comme auparavant.
Et voici ce que j’ai utilisé pour alléger le contenu de la barre d’état:
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
Définissez d'abord UIViewControllerBasedStatusBarAppearance
sur NO dans Info.plist . Ensuite, dans la méthode AppDelegate
's application:didFinishLaunchingWithOptions:
, ajoutez:
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
[application setStatusBarStyle:UIStatusBarStyleLightContent];
self.window.clipsToBounds = YES;
self.window.frame = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height-20);
self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);
}
return YES;
Ceci est une nouvelle fonctionnalité avec IOS7. Au lieu de regarder la barre de navigation de 20 px dans IOS7, fixant à 0 px. En guise de solution, déplacez l’ensemble de la vue sur 20 px ou utilisez l’image pour barre de navigation d’une hauteur de 64px.
dans la fenêtre iOS précédente, démarrez après la barre d'état et dans iOS 7, la fenêtre démarre à partir de 0px dans la version précédente (iPhone 5 et versions ultérieures), vous devez donc commencer à organiser la vue après 2o px ou à partir de 20 pixels.
vous pouvez écrire ci-dessous le code dans rootviewcontroller ou dans tout viewcontroller pour une vue définie à partir de 20px
#define IOS7_HEIGHT 64
- (void)viewDidLayoutSubviews {
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending)
{
CGRect frame=[self.view frame];
if (frame.Origin.y!=IOS7_HEIGHT) {
frame.Origin.y = IOS7_HEIGHT;
frame.size.height -= IOS7_HEIGHT;
[self.view setFrame:frame];
[self.view layoutSubviews];
}
}
}
ici height est 64 car 20 pour la barre d'état et 44 pour la barre de navigation . essayez ci-dessous le code cela vous aidera. et votre problème sera résolu.
Pour ceux qui rencontrent des problèmes pour mettre en œuvre la solution de @Masterfego (qui est également officielle, mais j'ai eu des problèmes avec Xcode 6.3 et des contraintes automatiques), voici ce que j'ai fait:
J'ai un UIViewController avec une barre de navigation ajoutée. J'ai sélectionné la barre de NAvigation et ajouté une contrainte de hauteur de 64px. Nous voyons plus tard un avertissement que la barre de navigation sera plus haute (mais c'est ce que nous faisons). Enfin, vous pouvez voir que la barre d'état a l'air agréable et a la même couleur que la barre de navigation. :)
PS: Je ne peux pas encore publier d’images.
Vous pouvez probablement créer des contraintes liées au guide de présentation supérieur pour spécifier la position de la barre de navigation par rapport à la barre d'état. Consultez la section Guide de transition de l'interface utilisateur iOS 7: Apparence et comportement pour plus d'informations sur l'utilisation des guides de présentation.
c’est la meilleure réponse… .. Mais je voulais savoir comment utiliser une variable Storyboard
et y glisser UINavigationBar
. Lorsque j’ai implémenté la méthode déléguée et que j’ai défini le résultat renvoyé sur UIBarPositionTopAttached
, cela ne fonctionnait pas.
- (void)viewDidLoad{
self.navigationbar.delegate = self;
}
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar{
NSLog(@"Got it");
//
// CGRect frame = self.navigaitonBar.frame;
//
// frame = CGRectMake(0, 20, CGRectGetWidth(frame), CGRectGetHeight(frame));
// self.navigaitonBar.frame = frame;
//
// NSLog(@"frame %f",frame.Origin.y);
return UIBarPositionTopAttached;
}
Si vous utilisez Xcode 6 et Swift, vous pouvez le créer:
J'étais confronté à un problème lorsque le plein écran ModalViewController
ouvrait à partir de ma MainViewController
, NavigationBar
était modifié lorsque l'utilisateur revenait à MainViewController
de ModalViewController
.
Le problème que j'ai remarqué est que la hauteur de la barre d'état n'était pas incluse lorsque l'utilisateur est revenu à MainViewController
. Veuillez déboguer et vérifier l’origine de votre NavigationBar
avant et après votre retour à votre ViewController
.
// This method will adjust navigation bar and view content.
private func adjustNavigationControllerIfNeeded() {
var frame = self.view.frame
let navigationBarHeight = self.navigationController!.navigationBar.frame.size.height
if(frame.Origin.y == navigationBarHeight && !UIApplication.shared.isStatusBarHidden) {
// If status bar height is not included but it is showing then we have to adjust
our Navigation controller properly
print("Adjusting navigation controller")
let statusBarHeight = UIApplication.shared.statusBarFrame.height
frame.Origin.y += statusBarHeight // Start view below navigation bar
frame.size.height -= statusBarHeight
self.view.frame = frame
self.navigationController!.navigationBar.frame.Origin.y = statusBarHeight // Move navigation bar
}
}
Et appelez-le à partir de la méthode viewWillAppear -
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.adjustNavigationControllerIfNeeded()
}