NavigationItem setTitle不适用于二级UIViewController

时间:2010-02-15 13:47:01

标签: iphone title uinavigationitem

在我的应用程序中,我有一个UITabBarController,UINavigationControllers像这样初始化

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

newsViewController是一个UIViewController。 当我按下标签栏中的按钮以使用newsViewController显示导航项时,导航栏中的标题设置为ok。在newsViewController中我有一个我在init之后调用的方法设置。在设置方法中,我设置这样的标题 [[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中的setup方法如下所示:

- (void) setup {
    self.navigationItem.hidesBackButton = YES;
    [self.navigationItem setTitle:@"my view"];
}
在newsViewController中我有viewDidLoad并尝试在那里设置标题但没有成功。

  • (void)viewDidLoad { self.navigationItem.title = @“测试”; [super viewDidLoad]; }

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

任何指针?我无法理解为什么标题设置不正确。

EDIT2:在阅读了一些内容并逐步使用调试器并将rootviewcontrollers与childViewControllers进行比较之后,我在设置self.title = @后在childViewController的viewDidLoad方法中观察到了这一点。 “title”创建了navigationItem,因此它不是零情况。在调试器中,当我展开_navigationItem变量时,字段_navigationBar在离开viewDidLoad后为nil,在rootViewControllers中,navigationBar为NOT NULL,标题就在那里。我读到如果navigationBar为null,标题将不会显示。在图像是我在debuger中看到的。 alt text 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 个答案:

答案 0 :(得分:2)

编辑#2

我查看了你的代码,一切似乎都没问题。对我来说,唯一不合适的是你将子视图添加到导航控制器而不是使用子控制器的navigationItem。我从来没有见过这样做过。每个ViewController都有一个UINavigationItem属性,表示视图控制器被推送到导航栏时。只需阅读文档概述了解一些背景知识。

该NavigationItem有一个标题,左键和右键你可以设置......我会尝试将你的按钮设置为这些属性,因为通过向导航控制器添加子视图,它可以用标题做一些时髦的事情。 ..再一次,我从来没有看到它按照你的方式完成,所以我不确定它是对还是错。您必须进行的唯一更改是将按钮更改为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方法负责初始化对象的值(这是一件好事)。

答案 1 :(得分:1)

您应该将setup代码移至viewDidLoad方法。已为您设置导航项时调用viewDidLoad

要设置标题,只需使用self.title = @"my view"; - 您不应直接在navigationItem上设置标题。

答案 2 :(得分:0)

问题的根源是我使用在此地址http://sebastiancelis.com/找到的方法添加的navigationBar的自定义背景图片。基本上发生了什么,我引用了作者:

  

通过使用类别,我们可以轻松实现   添加我们自己的setBackgroundImage:方法   并在我们创建时调用它   UINavigationBar或   UINavigationController的。这种方法   只会添加一个UIImageView作为   子视图到导航栏然后   将该子视图发送到其后面   上海华。

     

但是,如果你试试这个,你会的   很快就看出它只是那种   作品。 UIImageView绝对是   可见,甚至最初在   正确的z指数。 然而,一旦你   将视图控制器推送或弹出到   导航控制器的堆栈,你   会看到背景图片是   不再在后台。代替,   它阻挡了标题和导航   酒吧按钮。这绝对不是   我们想要什么。

当我发现这个改变navigationBar背景的解决方案时,我很确定我做对了,但似乎我没有......

再次感谢你的时间!