69

У меня есть иерархия вид контроллера и самый верхний контроллер отображается как модальный и хотел бы знать, как отобразить панель навигации при использованииpresentViewController и отображение навигационной панели

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

ответ

163

Это правда, что если вы представить вид контроллера модально на 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:^{ 

         }]; 

Вы должны увидеть панель навигации, когда ваше представление представлено модально.

+0

Это почти то, с чего я начал. Но причина, по которой я не использую 'presentModalViewController', заключается в том, что он отмечен как устаревший API. –

+0

это то, что было написано в классе UIViewController: // Отображение другого контроллера вида в качестве модального дочернего элемента. Использует вертикальный переход листа, если он анимирован. Этот метод был заменен на presentViewController: анимированный: завершение: // Будет DEPRECATED, планируйте соответственно. - (void) presentModalViewController: (UIViewController *) modalViewController анимированный: (BOOL) анимированный; так просто назовите новый метод и передайте nil для завершения, и вы должны быть хорошими. –

+0

Отличный ответ. Обновлено для использования '(void) presentViewController: (UIViewController *) viewControllerToPresent animated: (BOOL) завершение флага: (void (^) (void)) complete' –

0

Если вы не установили свойство modalPresentationStyle (как в UIModalPresentationFormSheet), панель навигации будет отображаться всегда. Чтобы обеспечить, всегда делайте

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

Это всегда отображает навигационную панель.

+0

Хм ..даже с фиксированной ссылкой на «topViewController», я все еще вижу такое же поведение. Я не думаю, что я добавляю другие контроллеры представлений в навигационный стек любым специальным способом. –

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

Это совсем не работает –

+0

Это решило мою проблему – Clement

22

Вы можете использовать:

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

Возвращаясь (я думаю):

[self.navigationController popToRootViewControllerAnimated:YES]; 
+3

Благодарим вас, лучший способ сделать это, если у вас уже есть дизайн контроллера навигации в вашем раскадровке. Вы мне очень помогли – phyzalis

+0

назад [self.navigationController popViewControllerAnimated: YES]; popToRoot - все возвращается к первому диспетчеру просмотра –

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 или что-то, оживить контроллер с переходом, а затем добавить его в viewControllers navigationController.

1

У меня была такая же проблема на 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:^{ 

    }]; 
} 
0

Я использую этот код. Это работает отлично в прошивкой 8.

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

Swift 3,0/4,0

Навигация:

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

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

Going Back:

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

Swift 2,0

Навигация:

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

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

Going Back:

self.dismissViewControllerAnimated(true, completion: nil) 
+0

Но как установить, когда я пытаюсь выполнить свой код, а затем настраивать навигационную панель, но я не могу изменить ее свойство, как цвет оттенка штриха, название и т. д. – Jaydip

+0

В чем ваш вопрос @Jaydip? –

+0

navigationBartintColor не изменяется – Jaydip

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) 
0

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

Свифта 3

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

Как чтобы добавить кнопку BACK к представленному UIViewController –

+0

@zulkarnainshah, что это? – BennyTheNerd