如何使用外观正确地子类化UINavigationBar

时间:2013-05-04 10:33:54

标签: ios ios5 uinavigationcontroller uinavigationbar uinavigationitem

这是我想要实现的目标: NavigationBar 注意:还有控制器的标题。

其他一些信息: -

  1. 此导航栏将显示在大约10个视图控制器上。
  2. 它不是导航控制器的一部分,因为不需要。
  3. 左侧的按钮是静态的(将始终位于导航栏上)。
  4. 右键不是静态的,不存在或不存在 不同的View Controllers有所不同。
  5. 左按钮用作滑动菜单(即菜单从左下方滑动)
  6. 我在设置中使用了故事板
  7. 问题 实现这一目标的正确方法是什么?

    现有代码 我试图实现这个,但我只能得到一个或另一个按钮,没有标题工作。为了实现背景,我使用了外观API,如下所示:

    didFinishLaunching ...

    // Custom Navigation Bar appearance setup
    [[UINavigationBar appearance] setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys:
                                                           [UIColor colorWithRed:245.0/255.0 green:245.0/255.0 blue:245.0/255.0 alpha:1.0], UITextAttributeTextColor,
                                                           [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5],UITextAttributeTextShadowColor,
                                                           [NSValue valueWithUIOffset:UIOffsetMake(0, 1)],
                                                           UITextAttributeTextShadowOffset,nil]];
    // Used to deal with the rotation of the nav bar when implemented outside of Navigation Controller
    [[UINavigationBar appearance] setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleHeight];
    [[UINavigationBar appearance] setContentMode:UIViewContentModeScaleAspectFit];
    
    // Set the background image
    UIImage *imageBg = [[UIImage imageNamed: @"mainNavBar"] resizableImageWithCapInsets:UIEdgeInsetsMake(0,5,0,5)];
    [[UINavigationBar appearance] setBackgroundImage:imageBg forBarMetrics:UIBarMetricsDefault];
    
    // Used to push the title down slightly when in Landscape and NavBar outside of Navigation Controller
    [[UINavigationBar appearance] setTitleVerticalPositionAdjustment:2 forBarMetrics:UIBarMetricsLandscapePhone];
    

    然后,我使用以下内容将UINavigationBar子类化为左键创建: UINavigationBar的子类:awakeFromNib

    UINavigationItem* ni = [[UINavigationItem alloc] init];
    UIButton *leftButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 38.0f, 29.0f)];
    [leftButton setImage:[UIImage imageNamed:@"menuBarItem"] forState:UIControlStateNormal];
    [leftButton addTarget:nil action:@selector(menuItemPressed:) forControlEvents:UIControlEventTouchUpInside];
    [leftButton setContentMode:UIViewContentModeScaleAspectFit];
    [leftButton setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin];
    UIBarButtonItem *b =[[UIBarButtonItem alloc] initWithCustomView:leftButton];
    ni.leftBarButtonItem = b;
    self.items = @[ni];
    

    然后在故事板中我向有问题的VC添加一个NavigationBar并链接到正确的子类。我还在该控制器的故事板中的导航栏中添加了一个额外的按钮项,并链接到插座。然后在VC中我尝试使用以下内容更新标题和右键:

    查看包含子类化导航栏的控制器:viewDidLoad

    // Set VC Title for NavBar
    self.title  = NSLocalizedString(@"NavBarHomeTitle", @"Navigation Bar - Home page title");
    
    // Setup the right navigation bar item
    UIImage *addImage = [UIImage imageNamed:@"addGameButton"];
    UIButton *addButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [addButton setFrame:CGRectMake(0, 0, addImage.size.width, addImage.size.height)];
    [addButton setBackgroundImage:addImage forState:UIControlStateNormal];
    [addButton addTarget:self action:@selector(addGameButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    [self.rightBarButtonItem setCustomView:addButton];
    

    结果是只有左键的导航栏。现在我相信这是由于上面的awakeFromNib代码为init初始化了一个新的UINavigationItem,因此我无法控制标题并为其添加一个按钮。我怎么能完成这个?这是最好的方法还是在其他方面我看不到任何关于如何处理这个问题的深入教程。

1 个答案:

答案 0 :(得分:10)

您最好的选择是使用导航控制器,它充当控制器,询问它当前正在显示的视图控制器并更新导航栏。

您应该将导航控制器子类化,而不是创建导航栏的子类。然后,只要显示的视图控制器发生更改,您就可以通过将左按钮项添加到该视图控制器的导航项来设置它。每个视图控制器都可以指定它需要的任何正确的条形按钮项目。

最简单的方法是让导航控制器充当自己的委托并实施navigationController:willShowViewController:。使用此方法,它可以访问传递的视图控制器的navigationItem并设置leftBarButtonItem。如果需要,您还可以访问导航和视图控制器的其他方法。

每个视图控制器也会在viewDidLoad中将其self.navigationItem.rightBarButtonItem(s)设置为适合其视图要求的按钮。比如你的'addGameButton'栏按钮。

以这种方式工作,外观将按照您的方式工作,视图控制器的标题将自动工作,您可以完全控制,以及导航控制器子类中的方法,以执行按钮和交互自定义。