1.網(wǎng)頁(yè)監(jiān)聽(tīng)APP返回鍵(原生goback)
假設(shè)需求:當(dāng)APP點(diǎn)擊原生導(dǎo)航欄左上角返回鍵時(shí),APP并不返回上級(jí)VC,而是讓UIWebView返回上級(jí)頁(yè)面。
1.1首先
新建CMWebViewController,讓其繼承UIViewController,即:
- CMWebViewController.h中有:
@interface CMWebViewController : UIViewController
1.2 其次
建議基于UIViewController自建一個(gè)BackButtonHandler的分類,如UIViewController+BackButtonHandler.h和UIViewController+BackButtonHandler.m。
- UIViewController+BackButtonHandler.h
#import <UIKit/UIKit.h>
@protocol BackButtonHandlerProtocol <NSObject>
@optional
-(BOOL)navigationShouldPopOnBackButton;
@end
@interface UIViewController (BackButtonHandler) <BackButtonHandlerProtocol>
@end
- UIViewController+BackButtonHandler.m
#import "UIViewController+BackButtonHandler.h"
@implementation UIViewController (BackButtonHandler)
@end
@implementation UINavigationController (ShouldPopOnBackButton)
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
if([self.viewControllers count] < [navigationBar.items count]) {
return YES;
}
BOOL shouldPop = YES;
UIViewController* vc = [self topViewController];
if([vc respondsToSelector:@selector(navigationShouldPopOnBackButton)]) {
shouldPop = [vc navigationShouldPopOnBackButton];
}
if(shouldPop) {
dispatch_async(dispatch_get_main_queue(), ^{
[self popViewControllerAnimated:YES];
});
} else {
// Workaround for iOS7.1. Thanks to @boliva - http://stackoverflow.com/posts/comments/34452906
for(UIView *subview in [navigationBar subviews]) {
if(0. < subview.alpha && subview.alpha < 1.) {
[UIView animateWithDuration:.25 animations:^{
subview.alpha = 1.;
}];
}
}
}
return NO;
}
3.最后
在實(shí)現(xiàn)文件CMWebViewController.m導(dǎo)入如上分類,并實(shí)現(xiàn)分類中BackButtonHandlerProtocol協(xié)議的navigationShouldPopOnBackButton方法。
- CMWebViewController.m
#import "CMWebViewController.h"
#import "UIViewController+BackButtonHandler.h"
@interface CMWebViewController ()<UIWebViewDelegate,JSObjcDelegate>
- (BOOL)navigationShouldPopOnBackButton
{
if ([_webView canGoBack]) {
[_webView goBack];
return NO;
}
return YES;
}
2.網(wǎng)頁(yè)監(jiān)聽(tīng)APP返回鍵(OC調(diào)用JS)
假設(shè)需求:APP隱藏原生導(dǎo)航欄,相當(dāng)于網(wǎng)頁(yè)全屏了,當(dāng)在APP中點(diǎn)擊網(wǎng)頁(yè)端的左上角返回鍵時(shí),APP退出UIWebView并返回上級(jí)VC頁(yè)面。
2.1 iOS端
CMWebViewController實(shí)現(xiàn)文件代碼
- 導(dǎo)入頭文件
#import <JavaScriptCore/JavaScriptCore.h>
@protocol JSObjcDelegate <JSExport>
//iosDelegate對(duì)象調(diào)用的JavaScript方法,必須聲明?。?!
- (void)getCall;
@end
- 代理及屬性
@interface OpenHelpWebViewController ()<JSObjcDelegate>
@property (nonatomic, strong) JSContext *jsContext;
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@end
- 設(shè)置JS-OC交互對(duì)象
- (void)webViewDidFinishLoad:(UIWebView *)webView {
// 設(shè)置javaScriptContext上下文
self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// 將iosDelegate對(duì)象指向自身
self.jsContext[@"iosDelegate"] = self;
self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
NSLog(@"異常信息:%@", exceptionValue);
};
}
- iosDelegate對(duì)象方法(恭候JS調(diào)用)
- (void)getCall{
NSLog(@"call");
// 之后在回調(diào)JavaScript的方法Callback把內(nèi)容傳出去
dispatch_async(dispatch_get_main_queue(), ^{
//APP返回上級(jí)頁(yè)面動(dòng)作
[self.navigationController popViewControllerAnimated:YES];
});
}
2.2 H5/JS端
- H5關(guān)鍵部分:布局元素ID
<header class="header test">
<span>

</span>
<h2 class="txt_cen">網(wǎng)頁(yè)端標(biāo)題</h2>
<div></div>
</header>
- JS關(guān)鍵部分:調(diào)用OC方法
<script type="text/javascript">
$("#backId").click(function(){
var flag = getTheFlagString("flag");
if(flag == "h5"){
history.go(-1);
}else if(android){
window.androidDelegate.getCall();
}else if(ios){
window.iosDelegate.getCall();
}
});
</script>