NavigationItem setTitle 不适用于二级 UIViewController

Sor*_*ohi 5 iphone title uinavigationitem

在我的应用程序中,我有一个带有 UINavigationControllers 初始化的 UITabBarControllers

UINavigationController *newsNavigationController = [[UINavigationController alloc] initWithRootViewController: newsViewControler];
Run Code Online (Sandbox Code Playgroud)

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];
Run Code Online (Sandbox Code Playgroud)

newsViewController 中的设置方法如下所示:

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

在 newsViewController 我有 viewDidLoad 并试图在那里设置标题但没有成功。

  • (void)viewDidLoad { self.navigationItem.title = @"Test"; [超级viewDidLoad]; }

如果在[self.navigationController pushViewController: newsViewController animated:YES]; 我编写[[self.navigationController.viewControllers objectAtIndex:0] setTitle:@"myTitle"];包含 UITableView 的 UIViewController之后,我得到了标题 myTitle 而不是我在触摸单元格时推送的 newsViewController。

任何指针?我不明白为什么标题设置不正确。

EDIT2:在阅读更多内容并使用调试器逐步完成我的代码并将 rootviewcontrollers 与 childViewControllers 进行比较后,我观察到在设置 self.title = @"title" 后 childViewController 的 viewDidLoad 方法中,navigationItem 是创建所以它不是零的情况。在调试器中,当我展开 _navigationItem 变量时,字段 _navigationBar 在离开 viewDidLoad 后为零,在 rootViewControllers 中,navigationBar 不是 NULL 并且标题在那里。我读到如果导航栏为空,标题将不会显示。在图像中是我在调试器中看到的。替代文字 http://img138.imageshack.us/img138/1513/picture2bq.png现在我正在朝这个方向搜索。

EDIT1:下面是 parentViewController、firstChildViewController 和第二个 ChildViewController 的代码。已查看 parentViewController(标题没问题)。我按下导航栏上的一个按钮,调用 bearbeitenAction -> 第一个孩子被推动(标题未显示)。在 firstChildViewController 的导航栏上,我有一个按钮,当按下该按钮时会在堆栈上推送一个新的 ViewController(secondChildViewController)。第二个 ChildViewController 的标题不行。当我按 Back 时,firstChildViewController 的标题显示为 Ok。

父视图控制器:

    //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];
}
Run Code Online (Sandbox Code Playgroud)

代码中的 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];
}
Run Code Online (Sandbox Code Playgroud)

代码中的 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";
}
Run Code Online (Sandbox Code Playgroud)

Sor*_*ohi 0

问题的根源是我使用在此地址http://sebastiancelis.com/找到的方法添加的导航栏的自定义背景图像。基本上发生的事情是,我引用作者的话:

通过使用类别,我们可以轻松添加自己的 setBackgroundImage: 方法,并在创建 UINavigationBar 或 UINavigationController 时调用它。此方法只是将 UIImageView 作为子视图添加到导航栏,然后将该子视图发送到其超级视图的后面。

然而,如果你尝试这样做,你很快就会发现它只是有效的。UIImageView 绝对可见,甚至最初位于正确的 z 索引处。但是,一旦您将视图控制器推送或弹出到导航控制器的堆栈上,您将看到背景图像不再位于背景中。相反,它会遮挡标题和导航栏按钮。这绝对不是我们想要的。

当我找到这个改变导航栏背景的解决方案时,我很确定我做对了,但似乎我没有。

再次感谢您的宝贵时间!