iOS-JavaScript交互方案:網(wǎng)頁(yè)監(jiān)聽(tīng)APP返回鍵(goback)+APP監(jiān)聽(tīng)網(wǎng)頁(yè)返回鍵(JS調(diào)用OC對(duì)象方法)

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.hUIViewController+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>
            ![](./testFile/backIcon.png)
        </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>

參考文獻(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容