presentViewController та відображення панелі навігації


100

У мене є ієрархія контролерів перегляду, і найпопулярніший контролер відображається як модальний, і я хотів би знати, як відображати панель навігації при використанні

'UIViewController:presentViewController:viewControllerToPresent:animated:completion'

Документи для 'presentViewController: анімовані: завершення:' Примітка:

'На iPhone та iPod touch представлений вигляд завжди є повноекранним. На iPad презентація залежить від значення властивості modalPresentationStyle. '

Для 'modalPresentationStyle' документи говорять:

Стиль презентації визначає, як модально представлений контролер перегляду відображається на екрані. На iPhone та iPod touch контролери модального перегляду завжди представлені на весь екран, але на iPad є кілька різних варіантів презентації.

Чи є спосіб переконатися, що навігаційна панель видно під рядком стану, як тільки відобразиться елемент управління переглядом? Чи слід інтерпретувати документ як: ви не маєте жодних варіантів iPhone / iPod та лише на iPad?

Раніше я використовував 'UIViewController:presentModalViewController:animated'функцію, яка працювала чудово, але, оскільки iOS 5.0, API застарілий, тому я переходжу на новий.

Візуально, те, що я хочу зробити, - це новий слайд контролера внизу екрана, як і колишній API.

[оновлення за допомогою коду]:

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

Відповіді:


193

Це правда, що якщо ви будете представляти контролер перегляду в режимі мода на iPhone, він завжди буде представлений на весь екран, незалежно від того, як ви його представите на контролері подання зверху навігаційного контролера чи будь-яким іншим способом. Але ви завжди можете показати панель навігації таким чином:

Замість того, щоб представляти цей контролер подання модально, подайте навігаційний контролер модально з його кореневим контролером подання, встановленим як контролер перегляду, який ви хочете:

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

                        }];

Ви повинні побачити панель навігації, коли ваш вигляд представлений модально.


Це з того, з чого я почав. Але я не використовую 'presentModalViewController' через те, що він відзначається як застарілий API.
Йонас Гарднер

це те, що написано в класі UIViewController: // Відображення іншого контролера перегляду як модального дочірнього пристрою. Використовує вертикальний перехід на аркуші, якщо анімований. Цей метод був замінений presentViewController: анімований: завершення: // Він буде ВИДАЛЕНО, плануйте відповідно. - (недійсний) presentModalViewController: (UIViewController *) анімація modalViewController: (BOOL) анімована; так що просто назвіть новий метод і передайте нуль для завершення, і ви повинні бути добре.
Manish Ahuja

Чудова відповідь. Оновлено для використання(void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion
Уейн,

2
Коли я намагаюся представити навігаційний контролер, він виходить з ладу ( 'NSInvalidArgumentException', reason: 'Pushing a navigation controller is not supported'). Як це може працювати?
морська риба

У моєму випадку він показує панель, але інший вміст розміщено неправильно під час представлення анімації. І тільки після цієї анімації вона стрибає в правильне положення.
В’ячаслав Герчичов

47

Swift 5.*

Навігація:

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

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

Повернутися:

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

Швидкий 2.0

Навігація:

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

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

Повернутися:

self.dismissViewControllerAnimated(true, completion: nil)

1
Але як встановити, коли я пробую ваш код, тоді встановлюю лише навігаційну панель, але я не можу змінити її властивість, наприклад, колір відтінку, заголовок тощо
Jaydip

Не пов’язане з цим запитанням, але ви можете знайти відповідь тут stackoverflow.com/questions/26008536/…
Таль Ціон

23

Чи можете ви використовувати:

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

Повертаючись назад (я думаю):

[self.navigationController popToRootViewControllerAnimated:YES];

3
Дякую, найкращий спосіб зробити це, якщо у вас вже є дизайн навігаційного контролера у вашій дошці. Ви мені дуже допомогли
фізаліс

повертається назад [self.navigationController popViewControllerAnimated: ТАК]; popToRoot - повертаємось назад до 1-го оглядача
Борис Гафуров

2

У мене була така сама проблема на ios7. Я назвав це в селекторі, і він працював як на ios7, так і на 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

Все, що [self.navigationController pushViewController:controller animated:YES];робить, - це анімувати перехід і додати його до стеку контролера навігації та деяких інших цікавих анімаційних елементів панелі навігації. Якщо ви не переймаєтесь анімаційною смугою, цей код повинен працювати. На новому контролері відображається смужка, і ви отримуєте інтерактивний поп-жест!

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

Редагувати: Вибачте, presentViewController заповнить весь екран. Вам потрібно буде зробити власний перехід за допомогою CGAffineTransform.translation або щось інше, анімувати контролер з переходом, а потім додати його до перегляду NaviController viewControllers.


1

Стрімкий 3

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

Як додати кнопку НАЗАД до представленого UIViewController
zulkarnain shah

1

Версія Swift: Тут представлено ViewController, який вбудований у навігаційний контролер.

    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

Я використовую цей код. Це добре працює в iOS 8.

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

0

Одне рішення

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

Якщо ви не встановили властивість modalPresentationStyle (наприклад, UIModalPresentationFormSheet), навігаційна панель відображатиметься завжди. Щоб забезпечити, завжди робіть

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

Це відображатиме панель навігації завжди.


Хм ... навіть з фіксованим посиланням на "topViewController", я все ще спостерігаю таку ж поведінку. Я не думаю, що я додаю інші контролери перегляду у стек навігації якимось особливим чином.
Йонас Гарднер

0

Якщо ви використовуєте NavigationController у Swift 2.x

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

0

спробуйте це

     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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.