iPhone: Показать модальный UITableViewController с панелью навигации - PullRequest
86 голосов
/ 05 января 2011

Я показываю модальное представление класса 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. Идеи?

Ответы [ 6 ]

144 голосов
/ 05 января 2011

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

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

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

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

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

36 голосов
/ 06 августа 2014

Вот один из способов отображения панели навигации для тех, кто использует раскадровки, предложенные Учебное пособие Apple по раскадровке .

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

  1. В виде структуры выберите View Controller.
  2. Выбрав контроллер представления, выберите «Редактор»> «Встроить»> «Контроллер навигации».
17 голосов
/ 10 декабря 2013

В 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];
}
7 голосов
/ 21 июня 2014

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

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

(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, например:

Presenter VC -> Presentee VC

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

5 голосов
/ 19 июня 2015

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

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

Затем просто добавьте переход путем перетаскивания элемента управления из исходного контроллера представления к цели (той, которую вы хотите показать модально), выберите «Представить модально», когда появится маленькое представление с вариантами выбора для типа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!";
    }
}

Надеюсь, это поможет!

5 голосов
/ 05 января 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...