美文网首页疯狂iOSiOS学习笔记iOS Developer
iOS-JavaScript交互方案:网页监听APP返回键(go

iOS-JavaScript交互方案:网页监听APP返回键(go

作者: 小码僧 | 来源:发表于2017-06-22 00:11 被阅读825次

    1.网页监听APP返回键(原生goback)

    假设需求:当APP点击原生导航栏左上角返回键时,APP并不返回上级VC,而是让UIWebView返回上级页面。

    1.1首先

    新建CMWebViewController,让其继承UIViewController,即:

    • CMWebViewController.h中有:
    @interface CMWebViewController : UIViewController
    

    1.2 其次

    建议基于UIViewController自建一个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.最后

    在实现文件CMWebViewController.m导入如上分类,并实现分类中BackButtonHandlerProtocol协议的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.网页监听APP返回键(OC调用JS)

    假设需求:APP隐藏原生导航栏,相当于网页全屏了,当在APP中点击网页端的左上角返回键时,APP退出UIWebView并返回上级VC页面。

    2.1 iOS端

    CMWebViewController实现文件代码

    • 导入头文件
    #import <JavaScriptCore/JavaScriptCore.h>
    
    @protocol JSObjcDelegate <JSExport>
    
    //iosDelegate对象调用的JavaScript方法,必须声明!!!
    - (void)getCall;
    
    @end
    
    • 代理及属性
    @interface OpenHelpWebViewController ()<JSObjcDelegate>
    @property (nonatomic, strong) JSContext *jsContext;
    @property (weak, nonatomic) IBOutlet UIWebView *webView;
    @end
    
    • 设置JS-OC交互对象
    - (void)webViewDidFinishLoad:(UIWebView *)webView {
        
        // 设置javaScriptContext上下文
        self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
        // 将iosDelegate对象指向自身
        self.jsContext[@"iosDelegate"] = self;
        
        self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
            context.exception = exceptionValue;
            NSLog(@"异常信息:%@", exceptionValue);
        };
    }
    
    • iosDelegate对象方法(恭候JS调用)
    - (void)getCall{
        
        NSLog(@"call");
        // 之后在回调JavaScript的方法Callback把内容传出去
        dispatch_async(dispatch_get_main_queue(), ^{
            
            //APP返回上级页面动作
            [self.navigationController popViewControllerAnimated:YES];
        });
    }
    

    2.2 H5/JS端

    • H5关键部分:布局元素ID
    <header class="header test">
            <span>
                ![](./testFile/backIcon.png)
            </span>
            <h2 class="txt_cen">网页端标题</h2>
            <div></div>
    </header>
    
    • JS关键部分:调用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>
    

    参考文献

    相关文章

      网友评论

        本文标题:iOS-JavaScript交互方案:网页监听APP返回键(go

        本文链接:https://www.haomeiwen.com/subject/tllxcxtx.html