首页 文章

NavigationItem setTitle不适用于二级UIViewController

提问于
浏览
4

在我的应用程序中,我有一个UITabBarController与UINavigationControllers初始化如下

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

newsViewController是一个UIViewController . 当我按下标签栏中的按钮以使用newsViewController显示导航项时,导航栏中的 Headers 设置为ok . 在newsViewController中我有一个我在init之后调用的方法设置 . 在设置方法中,我将 Headers 设置为 [[self navigationItem] setTitle:[category_c title]];

问题出现了,在我的newsViewController中我有一个tableView,当我触摸一个单元格时,我想用所选新闻推送一个UIViewController,并在导航栏中显示 Headers .

在UIViewController中我有相同的设置方法,我在其中设置如上所述的 Headers . 问题是没有显示 . 导航项不为null,因为我可以调用 self.navigationItem.hidesBackButton = YES; 并且每次都隐藏后退按钮但 Headers 不显示 .

当触摸单元格时,我创建并推送新闻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并试图在那里设置 Headers 但没有成功 .

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

如果 [self.navigationController pushViewController: newsViewController animated:YES]; 之后我写了包含UITableView的UIViewController获取 Headers myTitle而不是我触摸单元格时推送的newsViewController .

任何指针?我无法理解为什么 Headers 设置不正确 .

EDIT2: After reading a little more and going through my code with the debugger step by step and comparing the rootviewcontrollers with the childViewControllers i've observed that in the viewDidLoad method of the childViewController after setting self.title = @"title" the navigationItem is created so it's not the nil situation. In the debugger when i expand the _navigationItem variable the field _navigationBar is nil after leaving viewDidLoad, in the rootViewControllers the navigationBar is NOT NULL and the title is there. I read that if the navigationBar is null the title will not show up. In the image is what i've seen in the debuger. alt text http://img138.imageshack.us/img138/1513/picture2bq.png now i'm searching in this direction.

EDIT1: below is the code for the parentViewController, firstChildViewController and second ChildViewController. the parentViewController is viewed(the title is OK). I press a button on the navigationBar that calls bearbeitenAction -> the first child is pushed(title is not showed). On the navigation bar of the firstChildViewController i have a button that when is pressed pushes a new ViewController on the stack(secondChildViewController). The title of the second ChildViewController is not ok. When i press Back the title of the firstChildViewController is showed 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

    EDIT #2

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

    NavigationItem有一个 Headers ,左键和右键你可以设置...我会尝试将你的按钮设置为这些属性,因为通过向导航控制器添加子视图,它可以做一些时髦的 Headers ...再次,我从未见过你这样做的方式,所以我不确定它是对还是错 . 您必须进行的唯一更改是将按钮更改为UIBarButtonItem类 . 试试看 .

    Original

    根视图控制器在数组中的索引为0 ...所以如果你这样做:

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

    它将始终设置根的 Headers . 尝试在以下位置执行:

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

    在子控制器的viewWillAppear方法中进行这种设置可能更容易......这样您就不必在导航控制器的子节点中搜索正确的视图控制器 .

    希望这可以帮助

    EDIT 您可以尝试仅在init方法中设置 Headers :

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

    这样,您允许对象的init方法负责初始化对象的值(这是一件好事) .

  • 1

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

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

  • 0

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

    通过使用类别,我们可以轻松添加自己的setBackgroundImage:方法,并在创建UINavigationBar或UINavigationController时调用它 . 此方法只是将UIImageView作为子视图添加到导航栏,然后将该子视图发送到其超级视图的后面 . 但是,如果你试试这个,你会很快发现它只是有用的 . UIImageView绝对可见,甚至最初都在正确的z-index上 . 但是,一旦将视图控制器推入或弹出导航控制器的堆栈,您将看到背景图像不再在后台 . 相反,它会阻止 Headers 和导航栏按钮 . 这绝对不是我们想要的 .

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

    再次感谢你的时间!

相关问题