navigationItem setTitle не работает для UIViewController второго уровня

StackOverflow https://stackoverflow.com/questions/2266300

  •  20-09-2019
  •  | 
  •  

Вопрос

в моем приложении у меня есть UITabBarController с UINavigationControllers, инициализированным следующим образом

UINavigationController *newsNavigationController = [[UINavigationController alloc] initWithRootViewController: newsViewControler];

newsViewController - это UIViewController.Когда я нажимаю кнопку на панели вкладок, чтобы отобразить элемент навигации с помощью newsViewController, заголовок на панели навигации устанавливается в порядке.в newsViewController у меня есть настройка метода, который я вызываю после инициализации.В методе настройки я задаю заголовок следующим образом [[self navigationItem] setTitle:[category_c title]];

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

В UIViewController у меня есть тот же метод настройки, в котором я настраиваю заголовок, как указано выше.Проблема в том, что это не показано.Элемент навигации не равен нулю, потому что я могу вызвать self.navigationItem.hidesBackButton = YES; и он каждый раз скрывает кнопку возврата, но заголовок не отображается.

Я создаю и запускаю news UIViewController следующим образом при касании ячейки

if(newsViewController == nil){
        newsViewController = [[NewsViewController alloc] init];
        [newsViewController setup];
    }
    [self.navigationController pushViewController: newsViewController animated:YES];

Метод настройки в newsViewController выглядит следующим образом:

- (void) setup {
    self.navigationItem.hidesBackButton = YES;
    [self.navigationItem setTitle:@"my view"];
}

в newsViewController у меня есть viewDidLoad и я попытался установить там заголовок, но безуспешно.

  • (недействительный)viewDidLoad { self.navigationItem.title = @"Тест";[загрузка суперпросмотра];}

если после [self.navigationController pushViewController: newsViewController animated:YES]; я пишу [[self.navigationController.viewControllers objectAtIndex:0] setTitle:@"myTitle"]; UIViewController, содержащий UITableView, получает заголовок myTitle вместо newsViewController, который я нажал, когда коснулся ячейки.

есть какие-нибудь указания?я не могу понять, почему заголовок задан неправильно.

РЕДАКТИРОВАТЬ 2:Прочитав еще немного и пошагово просмотрев мой код с помощью отладчика и сравнив rootviewcontrollers с childViewControllers, я заметил, что в методе viewDidLoad childViewController после установки self.title = @"title" создается navigationItem, так что это не нулевая ситуация.В отладчике, когда я разворачиваю переменную _navigationItem, поле _navigationBar равно нулю после выхода из viewDidLoad, в rootViewControllers панель навигации НЕ равна НУЛЮ, и заголовок там есть.Я читал, что если значение NavigationBar равно null, заголовок не будет отображаться.На изображении показано то, что я видел в отладчике. альтернативный текст http://img138.imageshack.us/img138/1513/picture2bq.png сейчас я ищу в этом направлении.

РЕДАКТИРОВАТЬ 1:ниже приведен код для parentViewController, firstChildViewController и second childViewController.просмотрен parentViewController (название в порядке).Я нажимаю кнопку на панели навигации, которая вызывает bearbeitenAction -> нажимается первый дочерний элемент (заголовок не отображается).На панели навигации firstChildViewController у меня есть кнопка, которая при нажатии запускает новый ViewController в стеке (secondChildViewController).Название второго childViewController не в порядке.Когда я нажимаю назад, заголовок firstChildViewController отображается нормально.

parentViewController Родительский просмотрконтроллер:

    //MARK: -
    //MARK: Initialization methods
    - (void) setup {
        dataManipulator = [[DataManipulation alloc] init];
        dataManipulator.delegate = self;

        [self.tabBarItem initWithTitle:[NSString stringWithFormat:@"%@",[category_c title]] image:[UIImage newImageFromResource:[category_c icon]] tag:0];

        searchResults = nil;
        companyDetailsPushed = NO;
    }

    //MARK: -
    //MARK: ViewControllerMethods
    // Implement loadView to create a view hierarchy programmatically, without using a nib.
    - (void) loadView {
        NSLog(@"WatchlistViewController: loadView");

        UIView *mainView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] applicationFrame].size.width, [[UIScreen mainScreen] applicationFrame].size.height)] autorelease];
        [mainView setBackgroundColor:[UIColor whiteColor]];
        mainView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
        mainView.contentMode = UIViewContentModeScaleToFill;
        [mainView setAutoresizesSubviews:YES];

            companiesTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 44, [[UIScreen mainScreen] applicationFrame].size.width, 322)];
        companiesTable.delegate = self;
        companiesTable.dataSource = self;
        [mainView addSubview:companiesTable];
        [companiesTable release];

            self.view = mainView;
    }

    - (void)viewDidLoad {
        [super viewDidLoad];
        if(![[category_c subtitle] isEqualToString:@""]) {
            self.title = [category_c subtitle];
        }
        else {
            self.title = [category_c title];
        }
    }

    - (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

        if(companyDetailsViewController == nil) {
            companyDetailsViewController = [[CompanyDetailsScrollViewController alloc] init];
            [companyDetailsViewController setup];
        }

        [watchlistDoneBtn setHidden:TRUE];
        companyDetailsPushed = YES;

        if(viewMode == SearchViewMode)
            [companyDetailsViewController setCompany:[searchResults objectAtIndex:indexPath.row]];
        else if(viewMode == WatchlistViewMode)
            [companyDetailsViewController setCompany:[[[Financial_deAppDelegate sharedAppDelegate] watchlistCompanies] objectAtIndex:indexPath.row]];

        [[self navigationController] pushViewController:companyDetailsViewController animated:YES];
    }

- (void) bearbeitenAction:(UIButton *) sender {
    NSLog(@"Berbeiten btn was pressed");
    if(berbeitenViewController == nil){
        berbeitenViewController = [[BerbeitenViewController alloc] init];
        [berbeitenViewController setup];
    }
    [self.navigationController pushViewController:berbeitenViewController animated:YES];
}

firstChildViewController = berbeitenViewController в коде:

- (void) setup {
    self.navigationItem.hidesBackButton = YES;
}

// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
    NSLog(@"BerbeitenViewController: loadView");

    UIView *mainView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] applicationFrame].size.width, [[UIScreen mainScreen] applicationFrame].size.height)] autorelease];
    [mainView setBackgroundColor:[UIColor darkGrayColor]];
    mainView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    mainView.contentMode = UIViewContentModeScaleToFill;
    [mainView setAutoresizesSubviews:YES];

    berbeitenBackBtn = [[UIButton alloc] initWithFrame:CGRectMake(5, 23, 69, 36)];
    [berbeitenBackBtn setBackgroundImage:[UIImage newImageFromResource:@"back_btn.png"] forState:UIControlStateNormal];
    [berbeitenBackBtn addTarget:self action:@selector(popViewController:) forControlEvents:UIControlEventTouchUpInside];
    [berbeitenBackBtn setEnabled:TRUE];
    [self.navigationController.view addSubview:berbeitenBackBtn];
    [berbeitenBackBtn release];

    berbeitenAddBtn = [[UIButton alloc] initWithFrame:CGRectMake(260, 23, 55, 36)];
    [berbeitenAddBtn setBackgroundImage:[UIImage newImageFromResource:@"bearbeiten_add_btn.png"] forState:UIControlStateNormal];
    [berbeitenAddBtn addTarget:self action:@selector(addCompany:) forControlEvents:UIControlEventTouchUpInside];
    [berbeitenAddBtn setEnabled:TRUE];
    [self.navigationController.view addSubview:berbeitenAddBtn];
    [berbeitenAddBtn release];

    companiesTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] applicationFrame].size.width, 366)];
    companiesTable.delegate = self;
    companiesTable.dataSource = self;
    [mainView addSubview:companiesTable];
    [companiesTable release];

    self.view = mainView;
}

- (void)viewDidLoad {
    NSLog(@"BerbeitenViewController viewDidLoad");
    [super viewDidLoad];
    self.title = @"Edit watchlist";
}

//MARK: Buttons actions

- (void) popViewController:(UIButton *) sender {
    NSLog(@"Pop BerbeitenViewController");
    [self.navigationController popViewControllerAnimated:YES];
}

- (void) addCompany:(UIButton *) sender {
    NSLog(@"Berbeiten addCompany btn pushed");
    if(searchViewController == nil){
        searchViewController = [[SearchViewController alloc] init];
        [searchViewController setup];
    }
    [self.navigationController pushViewController:searchViewController animated:YES];
}

secondChildViewController = SearchViewController в коде

- (void) setup {
    self.navigationItem.hidesBackButton = YES;
}

// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
    NSLog(@"BerbeitenViewController: loadView");

    UIView *mainView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] applicationFrame].size.width, [[UIScreen mainScreen] applicationFrame].size.height)] autorelease];
    [mainView setBackgroundColor:[UIColor darkGrayColor]];
    mainView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    mainView.contentMode = UIViewContentModeScaleToFill;
    [mainView setAutoresizesSubviews:YES];

    searchViewBackBtn = [[UIButton alloc] initWithFrame:CGRectMake(5, 23, 69, 36)];
    [searchViewBackBtn setBackgroundImage:[UIImage newImageFromResource:@"back_btn.png"] forState:UIControlStateNormal];
    [searchViewBackBtn addTarget:self action:@selector(popViewController:) forControlEvents:UIControlEventTouchUpInside];
    [searchViewBackBtn setEnabled:TRUE];
    [self.navigationController.view addSubview:searchViewBackBtn];
    [searchViewBackBtn release];

    self.view = mainView;
}


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"Edit Watchlist";
}
Это было полезно?

Решение 3

источником проблемы было пользовательское фоновое изображение для панели навигации, которое я добавил, используя метод, найденный по этому адресу http://sebastiancelis.com/ .По сути, произошло следующее, и я цитирую автора:

Используя категорию, мы могли бы легко добавить наш собственный setBackgroundImage:метод и вызываем его всякий раз, когда мы создаем UINavigationBar или UINavigationController.Этот метод просто добавит UIImageView в качестве вложенного представления на панель навигации, а затем отправит это вложенное представление в конец своего супервизора.

Однако, если вы попробуете это, вы быстро увидите, что это работает только отчасти .UIImageView определенно виден и даже изначально имеет правильный z-индекс. Однако, как только вы нажмете или разместите контроллер просмотра в стеке навигационного контроллера, вы увидите, что фоновое изображение больше не находится в фоновом режиме.Вместо этого он блокирует заголовок и кнопки панели навигации .Это определенно не то, чего мы хотим.

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

еще раз спасибо вам за уделенное время!

Другие советы

ПРАВКА №2

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

У этого элемента навигации есть заголовок, левая кнопка и правая кнопка, которые вы можете установить...Я бы попробовал установить для ваших кнопок эти свойства, потому что, добавляя подвиды в навигационный контроллер, он мог бы делать что-то необычное с заголовком...Опять же, я никогда не видел, чтобы это делалось так, как это делаете вы, поэтому я не совсем уверен, правильно это или неправильно.Единственные изменения, которые вам нужно будет внести, - это перевести кнопки в класс UIBarButtonItem.Дайте ему попробовать.

Оригинал

Корневой контроллер представления находится в массиве с индексом 0...так что, если ты делаешь это:

[[self.navigationController.viewControllers objectAtIndex:0] setTitle:@"myTitle"]

он всегда будет устанавливать заголовок корневого каталога.Попробуйте сделать это в:

objectAtIndex:([self.navigationController.viewControllers count] - 1)

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

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

Редактировать Вы могли бы попробовать установить заголовок ТОЛЬКО в методе init:

-(id)init {
    if (self = [super init]) {
        self.title = @"My Title";
    }
    return self;
}

Таким образом, вы разрешаете методу init объекта отвечать за инициализацию значений объекта (что хорошо).

Вы должны переместить setup код для viewDidLoad метод вместо этого.Тот самый viewDidLoad вызывается, когда элемент навигации уже настроен для вас.

Чтобы задать заголовок, просто используйте self.title = @"my view"; - вы не должны устанавливать заголовок непосредственно в navigationItem.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top