2011-01-05 4 views
83

Я показываю модальный вид, который является классом UITableViewController. По какой-то причине он не покажет панель навигации, когда я ее покажу. Вот мой код:iPhone: Показать модальный UITableViewController с панелью навигации

SettingsCreateAccount *detailViewController = [[SettingsCreateAccount alloc] initWithStyle:UITableViewStyleGrouped]; 
    detailViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 
    detailViewController.navigationController.navigationBarHidden = NO; 
    [self.navigationController presentModalViewController:detailViewController animated:YES]; 
    detailViewController = nil; 
    [detailViewController release]; 

Я думал, что это было показано по умолчанию? Если это помогает, я вызываю это из другого класса, который также является UITableViewController, управляемый UINavigationController. Идеи?

ответ

139

Когда вы представляете контроллер модального вида, он не использует никаких существующих навигационных контроллеров или навигационных панелей. Если вы хотите отобразить панель навигации, вам нужно добавить панель навигации в качестве подсмотра вашего модального представления и представить ее так, как вы делаете.

Если вы хотите представить модальный контроллер с функцией навигации просмотра, вам необходимо представить модальную навигацию контроллер, содержащей ваши детали контроллер представления вместо этого, например, так:

SettingsCreateAccount *detailViewController = [[SettingsCreateAccount alloc] initWithStyle:UITableViewStyleGrouped]; 
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:detailViewController]; 
[detailViewController release]; 

navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 
[self presentModalViewController:navController animated:YES]; 
[navController release]; 

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

+0

Спасибо, я ценю объяснение, поэтому я знаю, что я сделал неправильно. –

+0

Добро пожаловать! – BoltClock

+0

Если вы используете раскадровку, для этого не требуется никакого кодирования. Хорошее решение! – Jelle

5

Если вам нужен только NavigationBar, вы можете добавить экземпляр UINavigationBar и присвоить ему BarItems.

+0

Это зависит от ViewController: я думаю, вы не можете добавить UINavigationBar в UITableViewController, не так ли? – Tobias

+0

В IB перейдите к редактору -> Вставить в контроллер навигации, и у вас будет панель навигации. Перетащите и добавьте BarButtonItems к этому. – AmitaiB

17

На iOS 7 и вы просто хотите, чтобы панель навигации на вашем модульном контроллере отображала название и некоторые кнопки? Попробуйте эту магию в вашем UITableViewController:

// in the .h 
@property (strong) UINavigationBar* navigationBar; 

//in the .m 
- (void)viewDidLoad { 
    [super viewDidLoad]; 

    self.navigationItem.title = @"Awesome"; 
    self.navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectZero]; 
    [self.view addSubview:_navigationBar]; 
    [self.navigationBar pushNavigationItem:self.navigationItem animated:NO]; 
} 

-(void)layoutNavigationBar{ 
    self.navigationBar.frame = CGRectMake(0, self.tableView.contentOffset.y, self.tableView.frame.size.width, self.topLayoutGuide.length + 44); 
    self.tableView.contentInset = UIEdgeInsetsMake(self.navigationBar.frame.size.height, 0, 0, 0); 
} 

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{ 
    //no need to call super 
    [self layoutNavigationBar]; 
} 

-(void)viewDidLayoutSubviews{ 
    [super viewDidLayoutSubviews]; 
    [self layoutNavigationBar]; 
} 
+0

Шов - отличный способ сделать что-то. но когда я получаю его на Static UITableViewController, я больше не могу прокручивать табличное представление. любая идея почему? –

+0

Удивительный! Буквально. – GoZoner

+0

Удивительное и чистое решение. – Ali

7

Я хочу поделиться тем, как принятое решение может быть использовано в проектах с раскадровки:

Простой подход положить в раскадровке пустой навигации контроллера перед VC, который должен быть представлен как модально, так что отношения выглядят так:

(Presenter VC) -> представляет собой модно -> (навигационный контроллер с контроллером, который будет представлен в качестве его корня).

Мы пробовали этот подход на некоторое время и заметили, что наши раскадровки становятся «загрязненными» большим количеством таких промежуточных навигационных контроллеров, когда каждый! из них используется исключительно для одного! презентация какого-либо другого контроллера, который мы хотим представить с помощью навигационной панели.

Наше текущее решение инкапсулировать код из принятого ответа на персонализированный Segue:

#import "ModalPresentationWithNavigationBarSegue.h" 

@implementation ModalPresentationWithNavigationBarSegue 

- (void)perform { 
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.destinationViewController]; 

    [self.sourceViewController presentViewController:navigationController animated:YES completion:nil]; 
} 
@end 

Имея это SEGUE в нашем проекте мы не создавали промежуточные элементы навигации в наших раскадровок больше, мы просто используем это ModalPresentationWithNavigationBarSegue как:

Presenter VC -> VC получатель подарка

Я надеюсь й в этом ответе будет полезно людям, которым нравится избегать ненужного дублирования в своих раскадрах приложений.

+0

Это лучший ответ. Никаких лишних помех в досках объявлений, и просто простое определение класса один раз! –

34

Вот один из способов отображения панели навигации для тех, кто использует раскадровки, предложенные Apple's Tutorial on Storyboard.

Поскольку диспетчер модального вида не добавляется в стек навигации, он не получает панель навигации от контроллера навигации контроллера табличного представления. Чтобы дать контроллеру представления навигационную панель, когда она представлена ​​в виде модально, встройте ее в свой собственный контроллер навигации.

  1. В режиме схемы выберите View Controller.
  2. С выбранным контроллером вида выберите «Редактор»> «Вставить»> «Контроллер навигации».
+0

Убедитесь, что вы добавили модальный переход к контроллеру навигации, а не TableViewController – bickster

+0

, это правильный путь! –

+4

Принятый ответ 4 года. Это должно быть новое. –

4

Я просто хотел добавить что-то к тому, что сказал @Scott. Его ответ, безусловно, самый простой и самый распространенный способ сделать это сейчас с помощью раскадровки, iOS 7 и 8 ... (и вскоре, 9).

Определенное добавление контроллера вида к раскадровке и вложение его, как описано в @Scott, - это правильный путь.

Затем просто добавьте segue, перетащив управление из контроллера источника на цель (тот, который вы хотите показать модально), выберите «Present Modally», когда появится маленький вид с вариантами выбора типа segue , Наверное, хорошо дать ему имя (в приведенном ниже примере я использую «presentMyModalViewController»).

Единственное, что мне было нужно, это отсутствие случая @ Скотта, когда вы хотите фактически передать некоторые данные этому модульно представленному контроллеру представления, встроенному в контроллер навигации.

Если вы захватите segue.destinationViewController, это будет UINavigationController, а не контроллер, встроенный в UINavigationController.

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

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    if ([segue.identifier isEqualToString:@"presentMyModalViewController"]) { 
     // This could be collapsed, but it's a little easier to see 
     // what's going on written out this way. 

     // First get the destination view controller, which will be a UINavigationController 
     UINavigationController *nvc = (UINavigationController *)segue.destinationViewController; 

     // To get the view controller we're interested in, grab the navigation controller's "topViewController" property 
     MyModalViewController *vc = (EmailReceiptViewController *)[nvc topViewController]; 

     // Now that we have the reference to our view controller, we can set its properties here: 
     vc.myAwesomeProperty = @"awesome!"; 
    } 
} 

Надеется, что это помогает!

Смежные вопросы