前置条件
在定制 H5 页面的导航栏样式前,您需要确保已经了解框架导航栏和 H5 容器相关知识,主要包括:
设置所有 H5 页面导航栏默认样式
在应用主题的基础上,若您需要指定所有 H5 页面统一的样式,可以通过监听 Nebula 容器提供的事件机制进行定制。
-
容器支持的事件,参见头文件
NebulaSDK/NBDefine.h
: -
自定义插件 监听事件需要进行定制:
@implementation MPPlugin4TitleView
- (void)pluginDidLoad
{
self.scope = kPSDScope_Scene;
// -- 返回区域
[self.target addEventListener:kNBEvent_Scene_NavigationItem_Left_Back_Create_Before withListener:self useCapture:NO];
[self.target addEventListener:kNBEvent_Scene_NavigationItem_Left_Back_Create_After withListener:self useCapture:NO];
[self.target addEventListener:kNBEvent_Scene_NavigationItem_Left_Close_Create_Before withListener:self useCapture:NO];
[self.target addEventListener:kNBEvent_Scene_NavigationItem_Left_Close_Create_After withListener:self useCapture:NO];
// -- 标题区域
[self.target addEventListener:kNBEvent_Scene_TitleView_Create_Before withListener:self useCapture:NO];
[self.target addEventListener:kNBEvent_Scene_TitleView_Create_After withListener:self useCapture:NO];
// -- 控制按钮区域
[self.target addEventListener:kNBEvent_Scene_NavigationItem_Right_Setting_Create_Before withListener:self useCapture:NO];
[self.target addEventListener:kNBEvent_Scene_NavigationItem_Right_Setting_Create_After withListener:self useCapture:NO];
[self.target addEventListener:kNBEvent_Scene_NavigationItem_Right_SubSetting_Create_After withListener:self useCapture:NO];
[self.target addEventListener:kNBEvent_Scene_NavigationItem_Right_Setting_Change withListener:self useCapture:NO];
// -- 进度条
[self.target addEventListener:kNBEvent_Scene_ProgressView_Create_Before withListener:self useCapture:NO];
[self.target addEventListener:kNBEvent_Scene_ProgressView_Create_After withListener:self useCapture:NO];
[super pluginDidLoad];
}
-
设置返回区域中返回按钮和关闭按钮的样式:
- (void)handleEvent:(PSDEvent *)event
{
[super handleEvent:event];
if ([kNBEvent_Scene_NavigationItem_Left_Back_Create_Before isEqualToString:event.eventType]) {
[event preventDefault];
event.context.currentViewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"取消" style:UIBarButtonItemStylePlain target:self action:@selector(onClickBack)];
}else if ([kNBEvent_Scene_NavigationItem_Left_Back_Create_After isEqualToString:event.eventType]){
// 修改返回按钮样式
NSArray *leftBarButtonItems = event.context.currentViewController.navigationItem.leftBarButtonItems;
if ([leftBarButtonItems count] == 1) {
if (leftBarButtonItems[0] && [leftBarButtonItems[0] isKindOfClass:[AUBarButtonItem class]]) {
// 在默认返回按钮基础上,修改返回箭头和文案颜色
AUBarButtonItem *backItem = leftBarButtonItems[0];
backItem.backButtonColor = [UIColor greenColor];
backItem.titleColor = [UIColor colorFromHexString:@"#00ff00"];
// 隐藏返回箭头
// backItem.hideBackButtonImage = YES;
// 隐藏返回文案:文案设置为透明,保留返回按钮 s 点击区域
// backItem.titleColor = [UIColor clearColor];
}
}
}else if ([kNBEvent_Scene_NavigationItem_Left_Close_Create_Before isEqualToString:event.eventType]){
// // 隐藏关闭按钮
// [event preventDefault];
// NBNavigationItemLeftCloseEvent *itemEvent = (NBNavigationItemLeftCloseEvent *)event;
// UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
// button.frame = CGRectMake(0, 0, 44, 44);
// button.backgroundColor = [UIColor greenColor];
// [button setTitle:@"Close" forState:UIControlStateNormal];
// itemEvent.customView = button;
}else if ([kNBEvent_Scene_NavigationItem_Left_Close_Create_After isEqualToString:event.eventType]){
// // 修改关闭按钮样式
// [event preventDefault];
// NBNavigationItemLeftCloseEvent *itemEvent = (NBNavigationItemLeftCloseEvent *)event;
// UIButton *closeButton = (UIButton *)itemEvent.customView;
// [closeButton setTitle:@"Close" forState:UIControlStateNormal];
// [closeButton setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
}
}
-
设置 H5 页面标题样式:
if ([kNBEvent_Scene_TitleView_Create_Before isEqualToString:event.eventType]) {
// 重写 TitleView 的样式
NBNavigationTitleViewEvent *e = (id)event;
[e preventDefault];
}else if ([kNBEvent_Scene_TitleView_Create_After isEqualToString:event.eventType]) {
// 更改已创建 TitleView 的样式
NBNavigationTitleViewEvent *e = (id)event;
[[e.titleView mainTitleLabel] setFont:[UIFont systemFontOfSize:16]];
[[e.titleView mainTitleLabel] setTextColor:[UIColor greenColor]];
[e.titleView mainTitleLabel].lineBreakMode = NSLineBreakByTruncatingMiddle;
}
-
设置 OptionMebu 控制按钮的样式:
if ([kNBEvent_Scene_NavigationItem_Right_Setting_Create_After isEqualToString:event.eventType] || [kNBEvent_Scene_NavigationItem_Right_SubSetting_Create_After isEqualToString:event.eventType]) {
// 更改已创建 RightBarItem 的样式
NBNavigationItemRightSettingEvent *settingEvent = (id)event;
settingEvent.adjustsWidthToFitText = YES;
settingEvent.maxWidth = [UIScreen mainScreen].bounds.size.width / 3.0f;
UIButton *button = settingEvent.customView;
button.titleLabel.font = [UIFont systemFontOfSize:14.0f];
CGRect frame = CGRectMake(0, 0, 22, 22);
button.frame = frame;
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
if (!CGSizeEqualToSize(button.bounds.size, frame.size)) {
button.frame = frame;
}
}
-
设置 H5 页面加载时进度条的样式:
if([kNBEvent_Scene_ProgressView_Create_After isEqualToString:event.eventType]){
NBProgressViewEvent *progressEvent = (NBProgressViewEvent *)event;
id<NBProgressViewProtocol> progressView = progressEvent.progressView;
[progressView setProgressTintColor:[UIColor greenColor]];
}
定制某个 H5 页面导航栏样式
若您需要定制某个 H5 页面导航栏的样式,根据修改时机不同,提供的方法也分为两类:页面加载前 与 页面打开后。
-
页面加载前:在默认导航栏样式基础上定制导航栏,主要分为以下两步:
-
自定义启动参数:当前 H5 页面加载时自定义启动参数,指定定制方式:
- 从 H5 页面进入另一个 H5 页面,传递自定义启动参数的方法参见 pushWindow 打开新页面 和 startApp 启动其他应用。
-
从 Native 页面进入一个 H5 页面,传递自定义启动参数的方法参考如下代码:
#pragma mark 进入页面时修改,H5 需通过启动参数设置
- (void)gotoHideNavigator
{
// 打开 H5 页面,隐藏导航栏
[[MPNebulaAdapterInterface shareInstance] startH5ViewControllerWithParams:@{@"url": @"https://tech.antfin.com", @"showTitleBar":@NO,@"transparentTitle":@"auto"}];
}
- (void)gotoShowNavigator
{
// 打开 H5 页面,显示导航栏
[[MPNebulaAdapterInterface shareInstance] startH5ViewControllerWithParams:@{@"url": @"https://tech.antfin.com", @"showTitleBar":@YES}];
}
- (void)gotoTransparency
{
// 打开 H5 页面,设置透明导航栏
[[MPNebulaAdapterInterface shareInstance] startH5ViewControllerWithParams:@{@"url": @"https://tech.antfin.com", @"transparentTitle":@"auto"}];
}
- (void)gotoUpdateBackgroundColor
{
// 修改导航栏背景颜色
[[MPNebulaAdapterInterface shareInstance] startH5ViewControllerWithParams:@{@"url": @"https://tech.antfin.com", @"titleBarColor":@"16775138"}];
}
- (void)gotoUpdateStatusBarStyle
{
// 修改状态栏颜色
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
- (void)gotoUpdateBackTitleColor
{
// 修改默认返回按钮文案颜色
[[MPNebulaAdapterInterface shareInstance] startH5ViewControllerWithParams:@{@"url": @"https://tech.antfin.com", @"backButtonColor":@"ff0000"}];
}
- (void)gotoUpdateTitleColor
{
// 修改标题颜色
[[MPNebulaAdapterInterface shareInstance] startH5ViewControllerWithParams:@{@"url": @"https://tech.antfin.com", @"titleColor":@"ff0000"}];
}
-
处理 H5 基类:在基类的
viewWillAppear
方法中,根据传入的启动参数调用 native 接口方法对导航栏样式进行修改:- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// 当前页面的 WebView
UIWebView *webView = (UIWebView *)self.psdContentView;
NSLog(@"[mpaas] webView: %@", webView);
// 当前页面的启动参数
NSDictionary *expandParams = self.psdScene.createParam.expandParams;
NSLog(@"[mpaas] expandParams: %@", expandParams);
if ([expandParams count] > 0) {
[self customNavigationBarWithParams:expandParams];
}
}
- (void)customNavigationBarWithParams:(NSDictionary *)expandParams
{
// 定制导航栏背景
NSString *titleBarColorString = expandParams[@"titleBarColor"];
if ([titleBarColorString isKindOfClass:[NSString class]] && [titleBarColorString length] > 0) {
UIColor *titleBarColor = [UIColor colorFromHexString:titleBarColorString];
[self.navigationController.navigationBar setNavigationBarStyleWithColor:titleBarColor translucent:NO];
[self.navigationController.navigationBar setNavigationBarBottomLineColor:titleBarColor];
}
//导航栏是否隐藏,默认不隐藏。设置隐藏后,webview 需全屏
NSString *showTitleBar = expandParams[@"showTitleBar"];
if (showTitleBar && ![showTitleBar boolValue]) {
self.options.showTitleBar = NO;
[self.navigationController setNavigationBarHidden:YES];
// 调整 webview 的位置
UIWebView *webView = (UIWebView *)[self psdContentView];
CGRect frame = webView.frame;
frame.origin.y = [[UIApplication sharedApplication] statusBarFrame].size.height;
frame.size.height -= [[UIApplication sharedApplication] statusBarFrame].size.height;
webView.frame = frame;
self.automaticallyAdjustsScrollViewInsets = NO;
}
//导航栏是否透明,默认不透明。设置透明后,webview 需全屏
NSString *transparentTitle = expandParams[@"transparentTitle"];
if ([transparentTitle isEqualToString:@"always"] || [transparentTitle isEqualToString:@"auto"]) {
// 导航栏和底部横线变为透明
UIColor *clearColor = [UIColor clearColor] ;
[self.navigationController.navigationBar setNavigationBarTranslucentStyle];
[self.navigationController.navigationBar setNavigationBarStyleWithColor:clearColor translucent:YES];
// 调整 webview 的位置
self.edgesForExtendedLayout = UIRectEdgeAll;
if (@available(iOS 11.0, *)) {
UIWebView *wb = (UIWebView *)[self psdContentView];
wb.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}else{
self.automaticallyAdjustsScrollViewInsets = NO;
}
}
// 修改默认返回按钮文案颜色
NSString *backButtonColorString = expandParams[@"backButtonColor"];
if ([backButtonColorString isKindOfClass:[NSString class]] && [backButtonColorString length] > 0) {
UIColor *backButtonColor = [UIColor colorFromHexString:backButtonColorString];
NSArray *leftBarButtonItems = self.navigationItem.leftBarButtonItems;
if ([leftBarButtonItems count] == 1) {
if (leftBarButtonItems[0] && [leftBarButtonItems[0] isKindOfClass:[AUBarButtonItem class]]) {
AUBarButtonItem *backItem = leftBarButtonItems[0];
backItem.titleColor = backButtonColor;
backItem.backButtonColor = backButtonColor;
}
}
}
// 设置标题颜色
NSString *titleColorString = expandParams[@"titleColor"];
if ([titleColorString isKindOfClass:[NSString class]] && [titleColorString length] > 0) {
UIColor *titleColor = [UIColor colorFromHexString:titleColorString];
id<NBNavigationTitleViewProtocol> titleView = self.navigationItem.titleView;
[[titleView mainTitleLabel] setFont:[UIFont systemFontOfSize:16]];
[[titleView mainTitleLabel] setTextColor:titleColor];
}
}
-
-
页面打开后:在用户操作的过程中动态修改导航栏样式。主要通过自定义 JSAPI 的方式,调用 native 接口方法进行修改。
- 自定义 JSAPI 对当前页面导航栏样式进行处理。
-
参考 定制某一个页面导航栏样式 提供的接口,在 JSAPI 中对原生导航栏进行处理:
- (void)handler:(NSDictionary *)data context:(PSDContext *)context callback:(PSDJsApiResponseCallbackBlock)callback
{
[super handler:data context:context callback:callback];
UIViewController *currentVC = context.currentViewController;
currentVC.navigationItem.titleView = [[AUDoubleTitleView alloc] initWithTitle:@"主标题" detailTitle:@"副标题"];
callback(@{@"success":@YES});
}