presentViewController i wyświetlanie paska nawigacji

100

Mam hierarchię kontrolera widoku i najwyższy kontroler jest wyświetlany jako modalny i chciałbym wiedzieć, jak wyświetlić pasek nawigacji podczas używania

'UIViewController:presentViewController:viewControllerToPresent:animated:completion'

Dokumentacja dla „presentViewController: animated: Complete:” Uwaga:

„Na iPhonie i iPodzie touch prezentowany widok jest zawsze na pełnym ekranie. Na iPadzie prezentacja zależy od wartości we właściwości modalPresentationStyle. '

W przypadku „modalPresentationStyle” dokumenty mówią:

Styl prezentacji określa, jak modalnie prezentowany kontroler widoku jest wyświetlany na ekranie. Na iPhonie i iPodzie touch kontrolery widoku modalnego są zawsze prezentowane na pełnym ekranie, ale na iPadzie jest kilka różnych opcji prezentacji.

Czy istnieje sposób, aby upewnić się, że pasek nawigacji jest widoczny pod paskiem stanu, gdy formant widoku zostanie wyświetlony? Czy powinienem interpretować dokument jako, że nie masz żadnych opcji dla iPhone'a / iPoda i tylko na iPadzie?

Wcześniej korzystałem z tego, 'UIViewController:presentModalViewController:animated'co działało dobrze, ale od iOS 5.0 API zostało wycofane, więc przechodzę na nowe.

Wizualnie chcę, aby nowy kontroler wsuwał się od dołu ekranu, tak jak robił to stary interfejs API.

[aktualizacja za pomocą kodu]:

// 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];
Jonas Gardner
źródło

Odpowiedzi:

193

Prawdą jest, że jeśli prezentujesz kontroler widoku modalnie na iPhonie, zawsze będzie on wyświetlany na pełnym ekranie, bez względu na to, jak go zaprezentujesz na kontrolerze widoku z góry kontrolera nawigacyjnego lub w inny sposób. Ale zawsze możesz wyświetlić pasek nawigacji w następujący sposób:

Zamiast prezentować ten kontroler widoku modalnie, zaprezentuj modalnie kontroler nawigacji z głównym kontrolerem widoku ustawionym jako żądany kontroler widoku:

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

                        }];

Powinieneś zobaczyć pasek nawigacyjny, gdy twój widok jest prezentowany modalnie.

Manish Ahuja
źródło
Od tego właściwie zacząłem. Ale powodem, dla którego nie używam „presentModalViewController”, jest fakt, że jest on oznaczony jako przestarzały interfejs API.
Jonas Gardner
oto, co zostało napisane w klasie UIViewController: // Wyświetl inny kontroler widoku jako modalne dziecko. Używa pionowego przejścia arkusza, jeśli animated.Ta metoda została zastąpiona przez presentViewController: animated: Complete: // Będzie DEPRECATED, zaplanuj odpowiednio. - (void) presentModalViewController: (UIViewController *) modalViewController animated: (BOOL) animated; więc po prostu wywołaj nową metodę i podaj nil na zakończenie, a wszystko powinno być dobre.
Manish Ahuja
Świetna odpowiedź. Zaktualizowano do użycia(void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion
Wayne
2
Kiedy próbuję przedstawić kontroler nawigacyjny, zawiesza się ( 'NSInvalidArgumentException', reason: 'Pushing a navigation controller is not supported'). Jak to działa?
oarfish
W moim przypadku pokazuje pasek, ale pozostała treść jest umieszczona nieprawidłowo na prezentacji animacji. I dopiero po tej animacji wskakuje na właściwą pozycję.
Vyachaslav Gerchicov
47

Swift 5.*

Nawigacja:

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

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

Wracać:

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

Swift 2.0

Nawigacja:

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

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

Wracać:

self.dismissViewControllerAnimated(true, completion: nil)
Tal Zion
źródło
1
Ale jak ustawić, kiedy wypróbowuję twój kod, ustawiam tylko pasek nawigacji, ale nie mogę zmienić jego właściwości, takich jak odcień paska, tytuł itp.
Jaydip
Nie dotyczy tego pytania, ale odpowiedź można znaleźć tutaj stackoverflow.com/questions/26008536/…
Tal Zion
23

Czy możesz użyć:

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

Wracając (chyba):

[self.navigationController popToRootViewControllerAnimated:YES];
marrop
źródło
3
Dziękuję, najlepszy sposób na zrobienie tego, jeśli masz już projekt kontrolera nawigacji w swojej serii ujęć. Bardzo mi pomogłeś
phyzalis
powrót to [self.navigationController popViewControllerAnimated: YES]; popToRoot - powrót do pierwszego kontrolera widoku
Boris Gafurov
2

Miałem ten sam problem na ios7. Nazwałem to w selektorze i działało zarówno na ios7, jak i 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: ^ {

    }];
}
Mohammad Parvez
źródło
1

Wszystko, co [self.navigationController pushViewController:controller animated:YES];robi, to animowanie przejścia i dodawanie go do stosu kontrolera nawigacji, a także innych fajnych elementów animacji paska nawigacji. Jeśli nie zależy Ci na animacji paska, ten kod powinien działać. Pasek pojawia się na nowym kontrolerze, a ty otrzymujesz interaktywny gest pop!

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

Edycja: Przepraszamy, presentViewController wypełni cały ekran. Będziesz musiał wykonać niestandardowe przejście za pomocą CGAffineTransform.translation lub czegoś podobnego, animować kontroler z przejściem, a następnie dodać go do viewControllers navigationControllera.

Ignat
źródło
1

Szybki 3

        let vc0 : ViewController1 = ViewController1()
        let vc2: NavigationController1 = NavigationController1(rootViewController: vc0)
        self.present(vc2, animated: true, completion: nil)
BennyTheNerd
źródło
Jak dodać przycisk WSTECZ do prezentowanego UIViewController
zulkarnain shah
1

Wersja Swift: przedstawia ViewController, który jest osadzony w kontrolerze nawigacji.

    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)

}
ioopl
źródło
1

Używam tego kodu. Działa dobrze w iOS 8.

MyProfileEditViewController *myprofileEdit=[self.storyboard instantiateViewControllerWithIdentifier:@"myprofileeditSid"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:myprofileEdit];
[self presentViewController:navigationController animated:YES completion:^{}];
Anil Prasad
źródło
0

Jedno rozwiązanie

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];
Yatin Sarbalia
źródło
0

Jeśli nie ustawiłeś właściwości modalPresentationStyle (np. UIModalPresentationFormSheet), pasek nawigacji będzie zawsze wyświetlany. Aby się upewnić, zawsze rób

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

Spowoduje to wyświetlenie paska nawigacji zawsze.

rakeshNS
źródło
Hmm ... nawet przy stałym odwołaniu do „topViewController” nadal widzę to samo zachowanie. Nie sądzę, żebym dodawał inne kontrolery widoku do stosu nawigacyjnego w żaden specjalny sposób.
Jonas Gardner
0

Jeśli używasz NavigationController w Swift 2.x

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let targetViewController = storyboard.instantiateViewControllerWithIdentifier("targetViewControllerID") as? TargetViewController
self.navigationController?.pushViewController(targetViewController!, animated: true)
Ego Slayer
źródło
0

Spróbuj tego

     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)
tsinghan
źródło