presentViewController et affichage de la barre de navigation


100

J'ai une hiérarchie de contrôleur de vue et le contrôleur le plus haut est affiché sous forme de modal et j'aimerais savoir comment afficher la barre de navigation lors de l'utilisation

'UIViewController:presentViewController:viewControllerToPresent:animated:completion'

La documentation de 'presentViewController: animated: completion:' note:

«Sur iPhone et iPod touch, la vue présentée est toujours en plein écran. Sur iPad, la présentation dépend de la valeur de la propriété modalPresentationStyle. '

Pour 'modalPresentationStyle', les documents disent:

Le style de présentation détermine la façon dont un contrôleur de vue présenté modalement est affiché à l'écran. Sur iPhone et iPod touch, les contrôleurs de vue modale sont toujours présentés en plein écran, mais sur iPad, il existe plusieurs options de présentation différentes.

Existe-t-il un moyen de s'assurer que la barre de navigation est visible sous la barre d'état une fois que le contrôle d'affichage s'affiche? Dois-je interpréter le document comme, vous n'obtenez aucune option d'iPhone / iPod et seulement sur iPad?

Auparavant, j'utilisais 'UIViewController:presentModalViewController:animated'ce qui fonctionnait bien, mais depuis iOS 5.0, l'API est obsolète, je passe donc à la nouvelle.

Visuellement, ce que je cherche à faire, c'est que le nouveau contrôleur se glisse du bas de l'écran, comme le faisait l'ancienne API.

[mise à jour avec code]:

// My root level view:
UIViewController *vc = [[RootViewController alloc] 
                            initWithNibName:nil 
                            bundle:[NSBundle mainBundle]];
navController = [[UINavigationController alloc] initWithRootViewController:vc];        
....

// Within the RootViewController, Second view controller is created and added 
// to the hierarchy. It is this view controller that is responsible for 
// displaying the DetailView:
SecondTierViewController *t2controller = [[SecondTierViewController alloc] 
                                           initWithNibName:nil
                                           bundle:[NSBundle mainBundle]];

[self.navigationController pushViewController:t2controller animated:YES];

// Created by SecondTierViewController 
DetailViewController *controller = [[DetailViewController alloc] initWithNibName:nil                                                                                 
                                        bundle:[NSBundle mainBundle]];  

controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
controller.modalPresentationStyle = UIModalPresentationCurrentContext;

[self.navigationController presentViewController:controller 
                                        animated:YES 
                                        completion:nil];

Réponses:


193

Il est vrai que si vous présentez un contrôleur de vue de manière modale sur l'iPhone, il sera toujours présenté en plein écran, quelle que soit la façon dont vous le présentez sur le contrôleur de vue de dessus d'un contrôleur de navigation ou de tout autre moyen. Mais vous pouvez toujours afficher la barre de navigation avec la solution de contournement suivante:

Plutôt que de présenter ce contrôleur de vue de manière modale, présentez un contrôleur de navigation de manière modale avec son contrôleur de vue racine défini comme contrôleur de vue souhaité:

MyViewController *myViewController = [[MyViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *navigationController = 
    [[UINavigationController alloc] initWithRootViewController:myViewController];

//now present this navigation controller modally 
[self presentViewController:navigationController
                   animated:YES
                   completion:^{

                        }];

Vous devriez voir une barre de navigation lorsque votre vue est présentée de manière modale.


C'est à peu près ce par quoi j'ai commencé. Mais la raison pour laquelle je n'utilise pas 'presentModalViewController' est qu'il est noté comme une API obsolète.
Jonas Gardner

c'est ce qui a été écrit dans la classe UIViewController: // Affiche un autre contrôleur de vue en tant qu'enfant modal. Utilise une transition de feuille verticale si animée. Cette méthode a été remplacée par presentViewController: animated: completion: // Elle sera DEPRECATED, planifiez en conséquence. - (void) presentModalViewController: (UIViewController *) modalViewController animé: (BOOL) animé; alors appelez simplement la nouvelle méthode et passez nil pour l'achèvement et vous devriez être bon.
Manish Ahuja

Très bonne réponse. Mise à jour pour utiliser(void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion
Wayne

2
Lorsque j'essaye de présenter un contrôleur de navigation, il plante ( 'NSInvalidArgumentException', reason: 'Pushing a navigation controller is not supported'). Comment cela peut-il fonctionner?
oarfish

Dans mon cas, il affiche une barre mais l'autre contenu est placé de manière incorrecte lors de la présentation de l'animation. Et seulement après cette animation, il saute dans la bonne position.
Vyachaslav Gerchicov

47

Swift 5.*

La navigation:

guard let myVC = self.storyboard?.instantiateViewController(withIdentifier: "MyViewController") else { return }
let navController = UINavigationController(rootViewController: myVC)

self.navigationController?.present(navController, animated: true, completion: nil)

Retourner:

self.dismiss(animated: true, completion: nil)

Swift 2.0

La navigation:

let myVC = self.storyboard?.instantiateViewControllerWithIdentifier("MyViewController");
let navController = UINavigationController(rootViewController: myVC!)

self.navigationController?.presentViewController(navController, animated: true, completion: nil)

Retourner:

self.dismissViewControllerAnimated(true, completion: nil)

1
Mais comment définir lorsque j'essaie votre code, puis ne définissez que la barre de navigation, mais je ne peux pas modifier sa propriété telle que la couleur de la teinte de la barre, le titre, etc.
Jaydip

Pas lié à cette question mais vous pouvez trouver la réponse ici stackoverflow.com/questions/26008536/…
Tal Zion

23

Peux tu utiliser:

[self.navigationController pushViewController:controller animated:YES];

Revenir en arrière (je pense):

[self.navigationController popToRootViewControllerAnimated:YES];

3
Merci, meilleure façon de le faire si vous avez déjà un design de contrôleur de navigation dans votre storyboard. Vous m'avez beaucoup aidé
phyzalis

revenir en arrière est [self.navigationController popViewControllerAnimated: YES]; popToRoot - retour au premier contrôleur de vue
Boris Gafurov

2

J'ai eu le même problème sur ios7. Je l'ai appelé dans selector et cela a fonctionné à la fois sur ios7 et ios8.

[self performSelector: @selector(showMainView) withObject: nil afterDelay: 0.0];

- (void) showMainView {
    HomeViewController * homeview = [
        [HomeViewController alloc] initWithNibName: @
        "HomeViewController"
        bundle: nil];
    UINavigationController * navcont = [
        [UINavigationController alloc] initWithRootViewController: homeview];
    navcont.navigationBar.tintColor = [UIColor whiteColor];
    navcont.navigationBar.barTintColor = App_Theme_Color;
    [navcont.navigationBar
    setTitleTextAttributes: @ {
        NSForegroundColorAttributeName: [UIColor whiteColor]
    }];
    navcont.modalPresentationStyle = UIModalPresentationFullScreen;
    navcont.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self.navigationController presentViewController: navcont animated: YES completion: ^ {

    }];
}

1

Tout ce que vous [self.navigationController pushViewController:controller animated:YES];faites est d'animer une transition et de l'ajouter à la pile de contrôleurs de navigation et à d'autres éléments d'animation de la barre de navigation sympas. Si vous ne vous souciez pas de l'animation de la barre, alors ce code devrait fonctionner. La barre apparaît sur le nouveau contrôleur et vous obtenez un geste pop interactif!

//Make Controller
DetailViewController *controller = [[DetailViewController alloc] initWithNibName:nil                                                                                 
                                    bundle:[NSBundle mainBundle]];  
//Customize presentation
controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
controller.modalPresentationStyle = UIModalPresentationCurrentContext;

//Present controller
[self presentViewController:controller 
                   animated:YES 
                 completion:nil];
//Add to navigation Controller
[self navigationController].viewControllers = [[self navigationController].viewControllers arrayByAddingObject:controller];
//You can't just [[self navigationController].viewControllers addObject:controller] because viewControllers are for some reason not a mutable array.

Edit: Désolé, presentViewController remplira le plein écran. Vous devrez faire une transition personnalisée, avec CGAffineTransform.translation ou quelque chose du genre, animer le contrôleur avec la transition, puis l'ajouter aux viewControllers de navigationController.


1

Swift 3

        let vc0 : ViewController1 = ViewController1()
        let vc2: NavigationController1 = NavigationController1(rootViewController: vc0)
        self.present(vc2, animated: true, completion: nil)

Comment ajouter le bouton RETOUR à l'UIViewController présenté
zulkarnain shah

1

Version Swift: Ceci présente un ViewController qui est intégré dans un contrôleur de navigation.

    override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    //  Identify the bundle by means of a class in that bundle.
    let storyboard = UIStoryboard(name: "Storyboard", bundle: NSBundle(forClass: SettingsViewController.self))

    // Instance of ViewController that is in the storyboard.
    let settingViewController = storyboard.instantiateViewControllerWithIdentifier("SettingsVC")

    let navController = UINavigationController(rootViewController: settingViewController)

    presentViewController(navController, animated: true, completion: nil)

}

1

J'utilise ce code. Cela fonctionne bien dans iOS 8.

MyProfileEditViewController *myprofileEdit=[self.storyboard instantiateViewControllerWithIdentifier:@"myprofileeditSid"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:myprofileEdit];
[self presentViewController:navigationController animated:YES completion:^{}];

0

Une solution

DetailViewController *controller = [[DetailViewController alloc] initWithNibName:nil                                                                                 
                                        bundle:[NSBundle mainBundle]];  

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
navController.modalPresentationStyle = UIModalPresentationCurrentContext;



[self.navigationController presentViewController:navController 
                                        animated:YES 
                                        completion:nil];

0

Si vous n'avez pas défini la propriété modalPresentationStyle (comme UIModalPresentationFormSheet), la barre de navigation sera toujours affichée. Pour vous assurer, faites toujours

[[self.navigationController topViewController] presentViewController:vieController 
                                                            animated:YES 
                                                          completion:nil];

Cela affichera toujours la barre de navigation.


Hmm .. même avec la référence fixe à «topViewController», je vois toujours le même comportement. Je ne pense pas que j'ajoute les autres contrôleurs de vue à la pile de navigation d'une manière particulière.
Jonas Gardner

0

Si vous utilisez NavigationController dans Swift 2.x

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let targetViewController = storyboard.instantiateViewControllerWithIdentifier("targetViewControllerID") as? TargetViewController
self.navigationController?.pushViewController(targetViewController!, animated: true)

0

essaye ça

     let transition: CATransition = CATransition()
    let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    transition.duration = 1
    transition.timingFunction = timeFunc
    transition.type = kCATransitionPush
    transition.subtype = kCATransitionFromRight
    self.view.window!.layer.addAnimation(transition, forKey: kCATransition)
    self.presentViewController(vc, animated:true, completion:nil)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.