全部产品
云市场
云游戏

iOS 定制导航栏

更新时间:2019-10-30 20:14:39

简介

在 App 开发的过程中,经常会要求对顶部导航栏进行自定义。本文将介绍在 基于 mPaaS 框架 创建的页面中,自定义导航栏的方法。包括以下内容:

基础概念

导航栏元素分布

导航栏元素主要分布在 3 个区域。一般对导航栏的定制化需求,最终都会变为对这几个区域的修改:导航栏元素.png

  1. back: 返回按钮控制区域,由 mPaaS 页面基类创建,默认样式为返回箭头 + “返回”文案。
  2. title/subTitle: 标题栏控制区域,默认不显示。若需显示,请调用系统方法设置当前页面的 title。
  3. optionMenu:页面菜单选项区域,默认不显示。如需显示,请调用系统方法设置当前页面的 rightNavigationItem。

导航栏结构

  • 如下图所示,基于 mPaaS 框架创建的应用,默认的 UI 结构为:window/navigationController > tabViewController > 每个 tab 嵌入一个 viewController。即应用主 window 的根应用是一个 UINavigationController 的对象,UINavigationController 的根应用是一个 UITabViewController

    导航栏结构

  • 由以上 UI 结构可以看出,整个应用全局只有一个 navigationController,因此所有页面共用同一个导航栏(默认使用 APNavigationBar 创建)。

    导航栏结构-UI.png

  • 为了统一所有页面的导航栏样式,要求 mPaaS 应用中,所有页面所在的 VC 都要继承 DTViewControoler,包括 native 和 H5 页面。

  • 基于 mPaaS 框架创建的应用的默认主题,主白底黑字蓝按钮:

    ddd

定制应用主题

每个应用都会有自己的主题风格,根据以下描述修改 mPaaS 应用的默认主题:

  • 修改导航栏背景色、返回控制区域、标题控制区域等,可重写 AUThemeManager 类的 au_defaultTheme_extraInfo 方法,修改以下 key 对应的返回值。

    • 接口方法 au_defaultTheme_extraInfo.png
    • 代码示例

      1. @implementation AUThemeManager (Portal)
      2. + (NSDictionary *)au_defaultTheme_extraInfo
      3. {
      4. NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
      5. dict[TITLEBAR_BACKGROUND_COLOR] = @"COLOR(#108EE9,1)"; // 导航栏背景色
      6. dict[TITLEBAR_LINE_COLOR] = @"COLOR(#108EE9,1)"; // 导航栏底部分割线或边线的颜色
      7. dict[TITLEBAR_TITLE_TEXTCOLOR] = @"COLOR(#ffffff,1)"; // 导航栏标题色
      8. dict[TITLEBAR_TITLE_TEXTSIZE_BOLD] = @"FONT(18)"; // 导航栏标题大小
      9. dict[TITLEBAR_TEXTCOLOR] = @"COLOR(#ffffff,1)"; // 导航栏返回按钮颜色
      10. return dict;
      11. }
      12. @end
      13. }

      重要:颜色值必须使用类如 COLOR(#108EE9,1) 的方式,否则会报错。

  • 修改主题配置中返回按钮图片,需重写 AUBarButtonItem 类中的 au_default_backButtonImg 方法。

    • 接口方法au_default_backButtonImg
    • 代码示例

      1. @implementation AUBarButtonItem (CGBBarButtonItem)
      2. + (UIImage *)au_default_backButtonImg
      3. {
      4. // 自定义返回按钮的图片
      5. return APCommonUILoadImage(@"back_button_normal_white");
      6. }
      7. @end
  • 修改所有页面的返回按钮样式和文案。

定制某一个页面导航栏样式

除了定制主题外,有时也需定制当前页面的导航栏的样式,如修改背景颜色、返回按钮样式等,根据修改时机不同,mPaaS 提供了不同的方法。

  • 页面加载前,在默认导航栏样式基础上修改导航栏颜色,可以在当前页面所在的 VC 中,实现 DTNavigationBarAppearanceProtocol 中的定义方法,来修改对应区域的颜色。

    • 接口方法DTNavigationBarAppearanceProtocol
    • 代码示例

      1. #pragma mark DTNavigationBarAppearanceProtocol:进入页面时修改导航栏样式
      2. - (UIColor *)opaqueNavigationBarColor
      3. {
      4. // 设置当前页面导航栏背景为红色
      5. return [UIColor redColor];
      6. // // 设置当前页面导航栏透明
      7. // return [UIColor colorWithRGB:0xff0000 alpha:0];
      8. }
      9. - (BOOL)autohideNavigationBar
      10. {
      11. // 设置当前页面导航栏是否隐藏
      12. return NO;
      13. }
      14. - (UIStatusBarStyle)customStatusBarStytle
      15. {
      16. // 设置当前页面状态栏样式
      17. return UIStatusBarStyleDefault;
      18. }
      19. - (UIColor *)customNavigationBarBackButtonTitleColor
      20. {
      21. // 设置当前页面返回按钮文案颜色
      22. return [UIColor greenColor];
      23. }
      24. - (UIImage *)customNavigationBarBackButtonImage
      25. {
      26. // 设置当前页面返回按钮图片
      27. return APCommonUILoadImage(@"back_button_normal_white");
      28. }
      29. - (UIColor *)customNavigationBarTitleColor
      30. {
      31. // 设置当前页面标题颜色
      32. return [UIColor greenColor];
      33. }
  • 页面打开后,在用户操作的过程中动态修改导航栏样式,如背景颜色滑动渐变、修改右侧菜单按钮等,根据修改的区域不同,主要分为以下几类:

    • 背景区域:包括隐藏/显示导航栏、透明导航栏、修改导航栏背景颜色、修改状态栏颜色。

      1. - (void)gotoHideNavigator
      2. {
      3. // 隐藏导航栏
      4. [self.navigationController.navigationBar setHidden:YES];
      5. }
      6. - (void)gotoShowNavigator
      7. {
      8. // 显示导航栏
      9. [self.navigationController.navigationBar setHidden:NO];
      10. }
      11. - (void)gotoTransparency
      12. {
      13. // 透明导航栏
      14. [self.navigationController.navigationBar setNavigationBarTranslucentStyle];
      15. }
      16. - (void)gotoUpdateBackgroundColor
      17. {
      18. // 修改导航栏背景颜色
      19. [self.navigationController.navigationBar setNavigationBarStyleWithColor:[UIColor whiteColor] translucent:NO];
      20. [self.navigationController.navigationBar setNavigationBarBottomLineColor:[UIColor whiteColor]];
      21. }
      22. - (void)gotoUpdateStatusBarStyle
      23. {
      24. // 修改状态栏颜色
      25. [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
      26. }
    • 返回控制区域:修改默认返回按钮文案颜色、修改默认返回按钮返回箭头样式、重新设置返回按钮样式。

      1. - (void)gotoUpdateBackTitleColor
      2. {
      3. // 修改默认返回按钮文案颜色
      4. NSArray *leftBarButtonItems = self.navigationItem.leftBarButtonItems;
      5. if ([leftBarButtonItems count] == 1) {
      6. if (leftBarButtonItems[0] && [leftBarButtonItems[0] isKindOfClass:[AUBarButtonItem class]]) {
      7. AUBarButtonItem *backItem = leftBarButtonItems[0];
      8. backItem.titleColor = [UIColor blackColor];
      9. }
      10. }
      11. }
      12. - (void)gotoUpdateBackImage
      13. {
      14. // 修改默认返回按钮返回箭头样式
      15. NSArray *leftBarButtonItems = self.navigationItem.leftBarButtonItems;
      16. if ([leftBarButtonItems count] == 1) {
      17. if (leftBarButtonItems[0] && [leftBarButtonItems[0] isKindOfClass:[AUBarButtonItem class]]) {
      18. AUBarButtonItem *backItem = leftBarButtonItems[0];
      19. backItem.backButtonImage = APCommonUILoadImage(@"back_button_normal");
      20. }
      21. }
      22. }
      23. - (void)gotoUpdateBackItem
      24. {
      25. // 重新设置返回按钮样式
      26. self.navigationItem.leftBarButtonItem = [AUBarButtonItem barButtonItemWithImageType:AUBarButtonImageTypeDelete target:self action:@selector(onClickBack)];
      27. }
      28. - (void)onClickBack
      29. {
      30. [self.navigationController popViewControllerAnimated:YES];
      31. }
    • 标题控制区域:修改默认标题颜色、设置上下主副标题、修改标题为图片显示。

      1. - (void)gotoUpdateTitleColor
      2. {
      3. // 修改标题颜色
      4. [self.navigationController.navigationBar setNavigationBarTitleTextAttributesWithTextColor:[UIColor blackColor]];
      5. }
      6. - (void)gotoTwoTitle
      7. {
      8. // 修改标题样式:上下主副标题
      9. self.navigationItem.titleView = [[AUDoubleTitleView alloc] initWithTitle:@"主标题" detailTitle:@"副标题"];
      10. }
      11. - (void)gotoTitleImage
      12. {
      13. // 修改标题样式:图片
      14. UIImageView *imageView = [[UIImageView alloc] initWithImage:APCommonUILoadImage(@"ilustration_ap_expection_alert")];
      15. imageView.frame = CGRectMake(0, 0, self.self.view.width-100, 64);
      16. self.navigationItem.titleView = imageView;
      17. }
    • 菜单控制区域:设置单个或多个右侧菜单按钮。

      1. - (void)gotoSetOptionMenu
      2. {
      3. // 设置右侧单按钮
      4. self.navigationItem.rightBarButtonItem = [AUBarButtonItem barButtonItemWithImageType:AUBarButtonImageTypeGroupChat target:self action:@selector(onClickRightItem)];
      5. }
      6. - (void)gotoSetTwoOptionMenu
      7. {
      8. // 设置右侧双按钮
      9. AUBarButtonItem *item1 = [AUBarButtonItem barButtonItemWithImageType:AUBarButtonImageTypeGroupChat target:self action:@selector(onClickRightItem)];
      10. AUBarButtonItem *item2 = [AUBarButtonItem barButtonItemWithImageType:AUBarButtonImageTypeHelp target:self action:@selector(onClickRightItem)];
      11. self.navigationItem.rightBarButtonItems = @[item1, item2];
      12. }
  • 沉浸式导航栏:进入时导航栏透明,滑动到指定位置后不透明。主要分为以下两类:

    • 进入页面时,设置导航栏透明:在当前页面所在的 VC 中重写以下接口。

      1. - (UIColor *)opaqueNavigationBarColor
      2. {
      3. // 设置当前页面导航栏透明
      4. return [UIColor colorWithRGB:0xff0000 alpha:0];
      5. }
    • 页面滑动到指定位置后,修改导航栏背景区域、返回区域、标题区域及菜单控制区域等样式。

      1. - (void)gotoUpdateBackgroundColor
      2. {
      3. // 修改导航栏背景颜色
      4. [self.navigationController.navigationBar setNavigationBarStyleWithColor:[UIColor whiteColor] translucent:NO];
      5. [self.navigationController.navigationBar setNavigationBarBottomLineColor:[UIColor whiteColor]];
      6. }
      7. - (void)gotoUpdateBackTitleColor
      8. {
      9. // 修改默认返回按钮文案颜色
      10. NSArray *leftBarButtonItems = self.navigationItem.leftBarButtonItems;
      11. if ([leftBarButtonItems count] == 1) {
      12. if (leftBarButtonItems[0] && [leftBarButtonItems[0] isKindOfClass:[AUBarButtonItem class]]) {
      13. AUBarButtonItem *backItem = leftBarButtonItems[0];
      14. backItem.titleColor = [UIColor blackColor];
      15. }
      16. }
      17. }
      18. - (void)gotoUpdateTitleColor
      19. {
      20. // 修改标题颜色
      21. [self.navigationController.navigationBar setNavigationBarTitleTextAttributesWithTextColor:[UIColor blackColor]];
      22. }