【问题标题】:How to subclass UINavigationBar correctly also using appearance如何使用外观正确地继承 UINavigationBar
【发布时间】:2013-04-28 17:01:07
【问题描述】:

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

一些附加信息:-

  1. 此导航栏将出现在大约 10 个视图控制器上。
  2. 它不是导航控制器的一部分,因为不是必需的。
  3. 左侧的按钮是静态的(将始终位于导航栏上)。
  4. 右键不是静态的,要么不存在,要么不存在 在不同的视图控制器上有所不同。
  5. 左键用作滑动菜单(即菜单从左下方滑入)
  6. 我在设置中使用故事板

问题 实现这一目标的正确方法是什么?

现有代码 我试图实现这一点,但我只能得到一个或另一个按钮,没有标题工作。为了实现背景,我使用了外观 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];

然后在情节提要中,我将 NavigationBar 添加到有问题的 VC 并链接到正确的子类。我还在情节提要的导航栏中为该控制器添加了一个额外的按钮项,并链接到一个插座。然后在 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 代码分配了一个新的 UINavigationItem,因此我无法控制标题并向其添加按钮。我怎样才能完成这个?这是最好的方法吗,还是有其他方法我看不到任何关于如何解决这个问题的深入教程。

【问题讨论】:

    标签: ios ios5 uinavigationcontroller uinavigationbar uinavigationitem


    【解决方案1】:

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

    与其子类化导航栏,不如子类化导航控制器。然后,每当显示的视图控制器更改时,您可以通过将左键项添加到该视图控制器的导航项来设置左键项。每个视图控制器都可以指定它需要的任何右栏按钮项。

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

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

    以这种方式工作,外观将如您所愿,视图控制器的标题将自动工作,您拥有完全控制权,以及导航控制器子类中的一些 if 方法,以执行您的按钮和交互自定义。

    【讨论】:

    • 谢谢,您能否提供更多有关如何完成此操作的信息?我了解导航控制器的子类化,但我不确定如何设置项目以及“..可以指定它需要的任何右栏按钮项目”......对于每个 VC?
    • 我认为这条路线的问题是我有大约 10 个视图控制器需要在它们自己的导航控制器中?还是您的意思是拥有一个导航控制器并每次推送一个新的根视图控制器?
    • 你们这10个视图控制器是如何相互关联的?
    • 我使用滑动菜单ECSlidingViewController。所以有一个控制器滑入左侧下方,从表格视图中选择不同的选项,新控制器将被推送到主视图。这被推送到 self.slidingviewcontroller.topviewcontroller 属性,该属性释放旧的并推送新的
    • 在这种情况下,每次进行新选择时,您都会创建导航控制器的实例,将视图控制器的实例设置为其根,并将导航控制器设置为滑动顶视图控制器。真的没有一个视图控制器有第二个(或细节)视图吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-17
    • 2011-05-03
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多