NavigationItem setTitle не работает для второго уровня UIViewController - PullRequest
4 голосов
/ 15 февраля 2010

в моем приложении у меня есть 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;, и он каждый раз скрывает кнопку, но заголовок не отображается.

Я создаю и нажимаю на новости 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 и я попытался установить заголовок, но безуспешно.

  • (void) viewDidLoad { self.navigationItem.title = @ "Test"; [super viewDidLoad]; } * * Тысяча двадцать-один

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

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

EDIT2: После того, как я прочитал немного больше и прошел шаг за шагом мой код с отладчиком и сравнил rootviewcontrollers с childViewControllers, я заметил, что в методе viewDidLoad childViewController после установки self.title = @ "заголовок" NavigationItem создан, так что это не ноль ситуации. В отладчике, когда я раскрываю переменную _navigationItem, поле _navigationBar становится равным nil после выхода из viewDidLoad, в rootViewControllers навигационная панель NOT NULL и заголовок присутствует. Я прочитал, что если навигационная панель нулевая, заголовок не будет отображаться. На изображении это то, что я видел в отладчике. альтернативный текст http://img138.imageshack.us/img138/1513/picture2bq.png Теперь я ищу в этом направлении.

EDIT1: ниже приведен код для parentViewController, firstChildViewController и второго ChildViewController. parentViewController просматривается (заголовок в порядке). Я нажимаю кнопку на панели навигации, которая вызывает bearbeitenAction -> первый дочерний элемент (заголовок не отображается). На панели навигации firstChildViewController у меня есть кнопка, которая при нажатии помещает новый ViewController в стек (secondChildViewController). Название второго ChildViewController не в порядке. Когда я нажимаю Back, заголовок firstChildViewController отображается Ok.

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 ]

2 голосов
/ 15 февраля 2010

РЕДАКТИРОВАТЬ # 2

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

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

Оригинал

Контроллер корневого представления имеет индекс 0 в массиве ... так что если вы делаете это:

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

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

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

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

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

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

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

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

1 голос
/ 15 февраля 2010

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

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

0 голосов
/ 17 февраля 2010

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

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

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

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

Еще раз спасибо за ваше время!

...