全部产品

定制 H5 页面导航栏

更新时间:2020-10-19 20:10:49

前置条件

在定制 H5 页面的导航栏样式前,您需要确保已经了解框架导航栏和 H5 容器相关知识,主要包括:

设置所有 H5 页面导航栏默认样式

在应用主题的基础上,若您需要指定所有 H5 页面统一的样式,可以通过监听 Nebula 容器提供的事件机制进行定制。

  • 容器支持的事件,参见头文件 NebulaSDK/NBDefine.h

    h5

  • 自定义插件 监听需要的事件进行定制化:

  1. @implementation MPPlugin4TitleView
  2. - (void)pluginDidLoad
  3. {
  4. self.scope = kPSDScope_Scene;
  5. // -- 返回区域
  6. [self.target addEventListener:kNBEvent_Scene_NavigationItem_Left_Back_Create_Before withListener:self useCapture:NO];
  7. [self.target addEventListener:kNBEvent_Scene_NavigationItem_Left_Back_Create_After withListener:self useCapture:NO];
  8. [self.target addEventListener:kNBEvent_Scene_NavigationItem_Left_Close_Create_Before withListener:self useCapture:NO];
  9. [self.target addEventListener:kNBEvent_Scene_NavigationItem_Left_Close_Create_After withListener:self useCapture:NO];
  10. // -- 标题区域
  11. [self.target addEventListener:kNBEvent_Scene_TitleView_Create_Before withListener:self useCapture:NO];
  12. [self.target addEventListener:kNBEvent_Scene_TitleView_Create_After withListener:self useCapture:NO];
  13. // -- 控制按钮区域
  14. [self.target addEventListener:kNBEvent_Scene_NavigationItem_Right_Setting_Create_Before withListener:self useCapture:NO];
  15. [self.target addEventListener:kNBEvent_Scene_NavigationItem_Right_Setting_Create_After withListener:self useCapture:NO];
  16. [self.target addEventListener:kNBEvent_Scene_NavigationItem_Right_SubSetting_Create_After withListener:self useCapture:NO];
  17. [self.target addEventListener:kNBEvent_Scene_NavigationItem_Right_Setting_Change withListener:self useCapture:NO];
  18. // -- 进度条
  19. [self.target addEventListener:kNBEvent_Scene_ProgressView_Create_Before withListener:self useCapture:NO];
  20. [self.target addEventListener:kNBEvent_Scene_ProgressView_Create_After withListener:self useCapture:NO];
  21. [super pluginDidLoad];
  22. }
  • 设置返回区域中返回按钮和关闭按钮的样式:
  1. - (void)handleEvent:(PSDEvent *)event
  2. {
  3. [super handleEvent:event];
  4. if ([kNBEvent_Scene_NavigationItem_Left_Back_Create_Before isEqualToString:event.eventType]) {
  5. [event preventDefault];
  6. event.context.currentViewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"取消" style:UIBarButtonItemStylePlain target:self action:@selector(onClickBack)];
  7. }else if ([kNBEvent_Scene_NavigationItem_Left_Back_Create_After isEqualToString:event.eventType]){
  8. // 修改返回按钮样式
  9. NSArray *leftBarButtonItems = event.context.currentViewController.navigationItem.leftBarButtonItems;
  10. if ([leftBarButtonItems count] == 1) {
  11. if (leftBarButtonItems[0] && [leftBarButtonItems[0] isKindOfClass:[AUBarButtonItem class]]) {
  12. // 在默认返回按钮基础上,修改返回箭头和文案颜色
  13. AUBarButtonItem *backItem = leftBarButtonItems[0];
  14. backItem.backButtonColor = [UIColor greenColor];
  15. backItem.titleColor = [UIColor colorFromHexString:@"#00ff00"];
  16. // 隐藏返回箭头
  17. // backItem.hideBackButtonImage = YES;
  18. // 隐藏返回文案:文案设置为透明,保留返回按钮 s 点击区域
  19. // backItem.titleColor = [UIColor clearColor];
  20. }
  21. }
  22. }else if ([kNBEvent_Scene_NavigationItem_Left_Close_Create_Before isEqualToString:event.eventType]){
  23. // // 隐藏关闭按钮
  24. // [event preventDefault];
  25. // NBNavigationItemLeftCloseEvent *itemEvent = (NBNavigationItemLeftCloseEvent *)event;
  26. // UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  27. // button.frame = CGRectMake(0, 0, 44, 44);
  28. // button.backgroundColor = [UIColor greenColor];
  29. // [button setTitle:@"Close" forState:UIControlStateNormal];
  30. // itemEvent.customView = button;
  31. }else if ([kNBEvent_Scene_NavigationItem_Left_Close_Create_After isEqualToString:event.eventType]){
  32. // // 修改关闭按钮样式
  33. // [event preventDefault];
  34. // NBNavigationItemLeftCloseEvent *itemEvent = (NBNavigationItemLeftCloseEvent *)event;
  35. // UIButton *closeButton = (UIButton *)itemEvent.customView;
  36. // [closeButton setTitle:@"Close" forState:UIControlStateNormal];
  37. // [closeButton setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
  38. }
  39. }
  • 设置 H5 页面标题样式:
  1. if ([kNBEvent_Scene_TitleView_Create_Before isEqualToString:event.eventType]) {
  2. // 重写 TitleView 的样式
  3. NBNavigationTitleViewEvent *e = (id)event;
  4. [e preventDefault];
  5. }else if ([kNBEvent_Scene_TitleView_Create_After isEqualToString:event.eventType]) {
  6. // 更改已创建 TitleView 的样式
  7. NBNavigationTitleViewEvent *e = (id)event;
  8. [[e.titleView mainTitleLabel] setFont:[UIFont systemFontOfSize:16]];
  9. [[e.titleView mainTitleLabel] setTextColor:[UIColor greenColor]];
  10. [e.titleView mainTitleLabel].lineBreakMode = NSLineBreakByTruncatingMiddle;
  11. }
  • 设置 OptionMebu 控制按钮的样式:
  1. if ([kNBEvent_Scene_NavigationItem_Right_Setting_Create_After isEqualToString:event.eventType] || [kNBEvent_Scene_NavigationItem_Right_SubSetting_Create_After isEqualToString:event.eventType]) {
  2. // 更改已创建 RightBarItem 的样式
  3. NBNavigationItemRightSettingEvent *settingEvent = (id)event;
  4. settingEvent.adjustsWidthToFitText = YES;
  5. settingEvent.maxWidth = [UIScreen mainScreen].bounds.size.width / 3.0f;
  6. UIButton *button = settingEvent.customView;
  7. button.titleLabel.font = [UIFont systemFontOfSize:14.0f];
  8. CGRect frame = CGRectMake(0, 0, 22, 22);
  9. button.frame = frame;
  10. [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
  11. if (!CGSizeEqualToSize(button.bounds.size, frame.size)) {
  12. button.frame = frame;
  13. }
  14. }
  • 设置 H5 页面加载时进度条的样式:
  1. if([kNBEvent_Scene_ProgressView_Create_After isEqualToString:event.eventType]){
  2. NBProgressViewEvent *progressEvent = (NBProgressViewEvent *)event;
  3. id<NBProgressViewProtocol> progressView = progressEvent.progressView;
  4. [progressView setProgressTintColor:[UIColor greenColor]];
  5. }

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

若您需要定制某个 H5 页面导航栏的样式,根据修改时机不同,提供的方法也分为两类:页面加载前页面打开后

  • 页面加载前:在默认导航栏样式基础上定制导航栏,主要分为以下两步:

    1. 自定义启动参数:当前 H5 页面加载时自定义启动参数,指定定制方式:

      1. #pragma mark 进入页面时修改,H5 需通过启动参数设置
      2. - (void)gotoHideNavigator
      3. {
      4. // 打开 H5 页面,隐藏导航栏
      5. [[MPNebulaAdapterInterface shareInstance] startH5ViewControllerWithParams:@{@"url": @"https://tech.antfin.com", @"showTitleBar":@NO,@"transparentTitle":@"auto"}];
      6. }
      7. - (void)gotoShowNavigator
      8. {
      9. // 打开 H5 页面,显示导航栏
      10. [[MPNebulaAdapterInterface shareInstance] startH5ViewControllerWithParams:@{@"url": @"https://tech.antfin.com", @"showTitleBar":@YES}];
      11. }
      12. - (void)gotoTransparency
      13. {
      14. // 打开 H5 页面,设置透明导航栏
      15. [[MPNebulaAdapterInterface shareInstance] startH5ViewControllerWithParams:@{@"url": @"https://tech.antfin.com", @"transparentTitle":@"auto"}];
      16. }
      17. - (void)gotoUpdateBackgroundColor
      18. {
      19. // 修改导航栏背景颜色
      20. [[MPNebulaAdapterInterface shareInstance] startH5ViewControllerWithParams:@{@"url": @"https://tech.antfin.com", @"titleBarColor":@"16775138"}];
      21. }
      22. - (void)gotoUpdateStatusBarStyle
      23. {
      24. // 修改状态栏颜色
      25. [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
      26. }
      27. - (void)gotoUpdateBackTitleColor
      28. {
      29. // 修改默认返回按钮文案颜色
      30. [[MPNebulaAdapterInterface shareInstance] startH5ViewControllerWithParams:@{@"url": @"https://tech.antfin.com", @"backButtonColor":@"ff0000"}];
      31. }
      32. - (void)gotoUpdateTitleColor
      33. {
      34. // 修改标题颜色
      35. [[MPNebulaAdapterInterface shareInstance] startH5ViewControllerWithParams:@{@"url": @"https://tech.antfin.com", @"titleColor":@"ff0000"}];
      36. }
    2. 处理 H5 基类:在基类的 viewWillAppear 方法中,根据传入的启动参数调用 native 接口方法对导航栏样式进行修改:

      1. - (void)viewWillAppear:(BOOL)animated
      2. {
      3. [super viewWillAppear:animated];
      4. // 当前页面的 WebView
      5. UIWebView *webView = (UIWebView *)self.psdContentView;
      6. NSLog(@"[mpaas] webView: %@", webView);
      7. // 当前页面的启动参数
      8. NSDictionary *expandParams = self.psdScene.createParam.expandParams;
      9. NSLog(@"[mpaas] expandParams: %@", expandParams);
      10. if ([expandParams count] > 0) {
      11. [self customNavigationBarWithParams:expandParams];
      12. }
      13. }
      14. - (void)customNavigationBarWithParams:(NSDictionary *)expandParams
      15. {
      16. // 定制导航栏背景
      17. NSString *titleBarColorString = expandParams[@"titleBarColor"];
      18. if ([titleBarColorString isKindOfClass:[NSString class]] && [titleBarColorString length] > 0) {
      19. UIColor *titleBarColor = [UIColor colorFromHexString:titleBarColorString];
      20. [self.navigationController.navigationBar setNavigationBarStyleWithColor:titleBarColor translucent:NO];
      21. [self.navigationController.navigationBar setNavigationBarBottomLineColor:titleBarColor];
      22. }
      23. //导航栏是否隐藏,默认不隐藏。设置隐藏后,webview 需全屏
      24. NSString *showTitleBar = expandParams[@"showTitleBar"];
      25. if (showTitleBar && ![showTitleBar boolValue]) {
      26. self.options.showTitleBar = NO;
      27. [self.navigationController setNavigationBarHidden:YES];
      28. // 调整 webview 的位置
      29. UIWebView *webView = (UIWebView *)[self psdContentView];
      30. CGRect frame = webView.frame;
      31. frame.origin.y = [[UIApplication sharedApplication] statusBarFrame].size.height;
      32. frame.size.height -= [[UIApplication sharedApplication] statusBarFrame].size.height;
      33. webView.frame = frame;
      34. self.automaticallyAdjustsScrollViewInsets = NO;
      35. }
      36. //导航栏是否透明,默认不透明。设置透明后,webview 需全屏
      37. NSString *transparentTitle = expandParams[@"transparentTitle"];
      38. if ([transparentTitle isEqualToString:@"always"] || [transparentTitle isEqualToString:@"auto"]) {
      39. // 导航栏和底部横线变为透明
      40. UIColor *clearColor = [UIColor clearColor] ;
      41. [self.navigationController.navigationBar setNavigationBarTranslucentStyle];
      42. [self.navigationController.navigationBar setNavigationBarStyleWithColor:clearColor translucent:YES];
      43. // 调整 webview 的位置
      44. self.edgesForExtendedLayout = UIRectEdgeAll;
      45. if (@available(iOS 11.0, *)) {
      46. UIWebView *wb = (UIWebView *)[self psdContentView];
      47. wb.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
      48. }else{
      49. self.automaticallyAdjustsScrollViewInsets = NO;
      50. }
      51. }
      52. // 修改默认返回按钮文案颜色
      53. NSString *backButtonColorString = expandParams[@"backButtonColor"];
      54. if ([backButtonColorString isKindOfClass:[NSString class]] && [backButtonColorString length] > 0) {
      55. UIColor *backButtonColor = [UIColor colorFromHexString:backButtonColorString];
      56. NSArray *leftBarButtonItems = self.navigationItem.leftBarButtonItems;
      57. if ([leftBarButtonItems count] == 1) {
      58. if (leftBarButtonItems[0] && [leftBarButtonItems[0] isKindOfClass:[AUBarButtonItem class]]) {
      59. AUBarButtonItem *backItem = leftBarButtonItems[0];
      60. backItem.titleColor = backButtonColor;
      61. backItem.backButtonColor = backButtonColor;
      62. }
      63. }
      64. }
      65. // 设置标题颜色
      66. NSString *titleColorString = expandParams[@"titleColor"];
      67. if ([titleColorString isKindOfClass:[NSString class]] && [titleColorString length] > 0) {
      68. UIColor *titleColor = [UIColor colorFromHexString:titleColorString];
      69. id<NBNavigationTitleViewProtocol> titleView = self.navigationItem.titleView;
      70. [[titleView mainTitleLabel] setFont:[UIFont systemFontOfSize:16]];
      71. [[titleView mainTitleLabel] setTextColor:titleColor];
      72. }
      73. }
  • 页面打开后:在用户操作的过程中动态修改导航栏样式。主要通过自定义 JSAPI 的方式,调用 native 接口方法进行修改。

    • 自定义 JSAPI 对当前页面导航栏样式进行处理。
    • 参考 定制某一个页面导航栏样式 提供的接口,在 JSAPI 中对原生导航栏进行处理:

      1. - (void)handler:(NSDictionary *)data context:(PSDContext *)context callback:(PSDJsApiResponseCallbackBlock)callback
      2. {
      3. [super handler:data context:context callback:callback];
      4. UIViewController *currentVC = context.currentViewController;
      5. currentVC.navigationItem.titleView = [[AUDoubleTitleView alloc] initWithTitle:@"主标题" detailTitle:@"副标题"];
      6. callback(@{@"success":@YES});
      7. }