IPhone: Показать модальный UITableViewController с панелью навигации
Я показываю модальное представление, которое является классом 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
. Идеи?
Ответы
Ответ 1
Когда вы представляете контроллер модального представления, он не использует никаких существующих навигационных контроллеров или навигационных панелей. Если вы хотите отобразить панель навигации, вам нужно добавить панель навигации в качестве подсмотра вашего модального представления и представить ее так, как вы делаете.
Если вы хотите представить контроллер модального вида с функциями навигации, вам нужно вместо этого представить модальный контроллер навигации, содержащий ваш контроллер представления подробностей, например:
SettingsCreateAccount *detailViewController = [[SettingsCreateAccount alloc] initWithStyle:UITableViewStyleGrouped];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
[detailViewController release];
navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:navController animated:YES];
[navController release];
Ваш модальный контроллер будет управлять своим собственным стекем навигации.
Ответ 2
Вот один из способов отображения панели навигации для тех, кто использует раскадровки, предложенные Apple Tutorial on Storyboard.
Поскольку контроллер модального представления не добавляется в стек навигации, он не получает панель навигации от контроллера навигации контроллера табличного представления. Чтобы дать контроллеру вида навигационную панель, когда она представлена модально, встройте ее в свой собственный контроллер навигации.
- В представлении схемы выберите "Просмотр контроллера".
- С выбранным контроллером просмотра выберите "Редактор" > "Вставить" > "Контроллер навигации".
Ответ 3
На 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];
}
Ответ 4
Я хочу поделиться тем, как принятое решение можно использовать в проектах с раскадными версиями:
Простой подход заключается в том, чтобы поставить пульт управления навигацией раскадровки перед VC, который должен быть представлен модально, поэтому отношения выглядят следующим образом:
(Presenter VC) → представляет модально → (навигационный контроллер с контроллером, который будет представлен в качестве его корня).
Мы пробовали этот подход на некоторое время и заметили, что наши раскадровки становятся "загрязненными" большим количеством таких промежуточных навигационных контроллеров, когда каждый! из них используется исключительно для одного! презентация какого-либо другого контроллера, который мы хотим представить с помощью навигационной панели.
Нашим текущим решением является инкапсуляция кода из принятого ответа в пользовательский сегмент:
#import "ModalPresentationWithNavigationBarSegue.h"
@implementation ModalPresentationWithNavigationBarSegue
- (void)perform {
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.destinationViewController];
[self.sourceViewController presentViewController:navigationController animated:YES completion:nil];
}
@end
В этом проекте мы не создаем промежуточных навигационных контроллеров в наших раскадках, мы просто используем этот ModalPresentationWithNavigationBarSegue, например:
Ведущий VC → Presentee VC
Я надеюсь, что этот ответ будет полезен для людей, которым нравится избегать ненужного дублирования в своих раскадрах приложений.
Ответ 5
Если вам нужен только NavigationBar
, вы можете добавить экземпляр UINavigationBar
и назначить ему BarItems.
Ответ 6
Я просто хотел добавить что-то к тому, что сказал @Scott. Его ответ, безусловно, самый простой и наиболее приемлемый способ сделать это сейчас с помощью раскадровки, iOS 7 и 8... (и вскоре, 9).
Определенное добавление контроллера просмотра в раскадровку и его внедрение, как описано в @Scott, - правильный путь.
Затем просто добавьте segue, перетащив управление с контроллера исходного вида на объект (тот, который вы хотите показать модально), выберите "Present Modally", когда появится небольшое представление с выбором типа segue. Наверное, хорошо дать ему имя (в приведенном ниже примере я использую "presentMyModalViewController" ).
Одна вещь, в которой я нуждалась, отсутствовала, это случай @Scott - это когда вы хотите передать некоторые данные этому модульно представленному контроллеру представления, встроенному в контроллер навигации.
Если вы захватите segue.destinationViewController, это будет UINavigationController, а не контроллер, встроенный в UINavigationController.
Итак, чтобы получить встроенный контроллер просмотра внутри контроллера навигации, вот что я сделал:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"presentMyModalViewController"]) {
// This could be collapsed, but it a little easier to see
// what 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 "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!";
}
}
Надеюсь, это поможет!