presentViewController e la visualizzazione della barra di navigazione


100

Ho una gerarchia del controller di visualizzazione e il controller più in alto viene visualizzato come modale e vorrei sapere come visualizzare la barra di navigazione durante l'utilizzo

'UIViewController:presentViewController:viewControllerToPresent:animated:completion'

La documentazione per "presentViewController: animated: completamento:" nota:

'Su iPhone e iPod touch, la vista presentata è sempre a schermo intero. Su iPad, la presentazione dipende dal valore nella proprietà modalPresentationStyle. '

Per "modalPresentationStyle", i documenti dicono:

Lo stile di presentazione determina il modo in cui un controller di visualizzazione presentato in modo modale viene visualizzato sullo schermo. Su iPhone e iPod touch, i controller di visualizzazione modale sono sempre presentati a schermo intero, ma su iPad sono disponibili diverse opzioni di presentazione.

C'è un modo per garantire che la barra di navigazione sia visibile sotto la barra di stato una volta che viene visualizzato il controllo della vista? Devo interpretare il documento come se non avessi alcuna opzione su iPhone / iPod e solo su iPad?

In precedenza, stavo usando 'UIViewController:presentModalViewController:animated'che funzionava bene, ma da iOS 5.0, l'API è stata deprecata, quindi sto passando a quella nuova.

Visivamente, quello che sto cercando di fare è far scorrere il nuovo controller dalla parte inferiore dello schermo, proprio come faceva la vecchia API.

[aggiornamento con codice]:

// 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];

Risposte:


193

È vero che se presenti un controller di visualizzazione in modo modale sull'iPhone, verrà sempre presentato a schermo intero, indipendentemente da come lo presenti sul controller di visualizzazione superiore di un controller di navigazione o in qualsiasi altro modo. Ma puoi sempre mostrare la barra di navigazione con la seguente soluzione alternativa:

Piuttosto che presentare quel controller di visualizzazione in modo modale, presentare un controller di navigazione in modo modale con il controller di visualizzazione principale impostato come controller di visualizzazione desiderato:

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:^{

                        }];

Dovresti vedere una barra di navigazione quando la tua vista è presentata in modo modale.


Questo è più o meno quello con cui ho iniziato. Ma il motivo per cui non utilizzo "presentModalViewController" è perché è indicato come un'API deprecata.
Jonas Gardner

questo è ciò che è stato scritto nella classe UIViewController: // Visualizza un altro controller di visualizzazione come figlio modale. Utilizza una transizione foglio verticale se animata. Questo metodo è stato sostituito da presentViewController: animated: completamento: // Sarà DEPRECATO, pianifica di conseguenza. - (void) presentModalViewController: (UIViewController *) modalViewController animated: (BOOL) animated; quindi chiama semplicemente il nuovo metodo e passa a zero per il completamento e dovresti essere bravo.
Manish Ahuja

Bella risposta. Aggiornato per l'uso(void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion
Wayne

2
Quando provo a presentare un controller di navigazione, si blocca ( 'NSInvalidArgumentException', reason: 'Pushing a navigation controller is not supported'). Come può funzionare?
oarfish

Nel mio caso mostra la barra ma l'altro contenuto è posizionato in modo errato sulla presentazione dell'animazione. E solo dopo questa animazione salta nella posizione corretta.
Vyachaslav Gerchicov

47

Swift 5.*

Navigazione:

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

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

Tornare indietro:

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

Swift 2.0

Navigazione:

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

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

Tornare indietro:

self.dismissViewControllerAnimated(true, completion: nil)

1
Ma come impostare quando provo il tuo codice, quindi imposta solo la barra di navigazione ma non posso modificare la sua proprietà come il colore della tinta della barra, il titolo ecc.
Jaydip

Non correlato a questa domanda, ma puoi trovare la risposta qui stackoverflow.com/questions/26008536/…
Tal Zion

23

Puoi usare:

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

Tornando indietro (credo):

[self.navigationController popToRootViewControllerAnimated:YES];

3
Grazie, il modo migliore per farlo se hai già un design del controller di navigazione nel tuo storyboard. Mi hai aiutato molto
phyzalis

tornare indietro è [self.navigationController popViewControllerAnimated: YES]; popToRoot - tornando indietro al primo viewcontroller
Boris Gafurov

2

Ho avuto lo stesso problema su iOS7. L'ho chiamato nel selettore e ha funzionato sia su ios7 che su 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

Tutto ciò che [self.navigationController pushViewController:controller animated:YES];fa è animare una transizione e aggiungerla allo stack del controller di navigazione e ad altri fantastici elementi di animazione della barra di navigazione. Se non ti interessa l'animazione della barra, questo codice dovrebbe funzionare. La barra appare sul nuovo controller e ottieni un gesto pop interattivo!

//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.

Modifica: Siamo spiacenti, presentViewController riempirà lo schermo intero. Dovrai fare una transizione personalizzata, con CGAffineTransform.translation o qualcosa del genere, animare il controller con la transizione, quindi aggiungerlo ai viewControllers del navigationController.


1

Swift 3

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

Come aggiungere il pulsante INDIETRO all'UIViewController presentato
zulkarnain shah

1

Versione Swift: presenta un ViewController incorporato in un controller di navigazione.

    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

Uso questo codice. Funziona bene in iOS 8.

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

0

Una soluzione

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

Se non hai impostato la proprietà modalPresentationStyle (come UIModalPresentationFormSheet), la barra di navigazione verrà sempre visualizzata. Per assicurarti, fallo sempre

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

Questo mostrerà sempre la barra di navigazione.


Hmm .. anche con il riferimento fisso a "topViewController", vedo ancora lo stesso comportamento. Non penso di aggiungere gli altri controller di visualizzazione allo stack di navigazione in alcun modo speciale.
Jonas Gardner

0

Se utilizzi NavigationController in Swift 2.x

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

0

prova questo

     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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.