zoukankan      html  css  js  c++  java
  • UIWebView中的JS和OC的互调

    html的代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <html>
    <head>
        <meta xmlns="http://www.w3.org/1999/xhtml" http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>这是一个示例html文件</title>
        <script Type='text/javascript'>
            function clickme() {
                alert('点击按钮了XXX!');
            }
        </script>
    </head>
    <body>
        <h1>欢迎欢迎!</h1>
        <!-- 自定义协议与OC进行交互,提示一定要有 /// -->
        <a href="myfunc:///showMessage:/晚上请你吃饭:D">你猜</a>
        <hr />
        <a href="http://m.baidu.com">百度一下,你就知道!</a>
    </body>
    </html>

    1。OC中调用html的代码

    要执行html中的js,需要加载完成网页之后再执行,

    1
    UIWebViewDelegate协议
    1
    2
    3
    4
    5
    6
    7
    8
    9
    @protocol UIWebViewDelegate <NSObject>
     
    @optional
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
    - (void)webViewDidStartLoad:(UIWebView *)webView;
    - (void)webViewDidFinishLoad:(UIWebView *)webView;
    - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;
     
    @end
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    - (void)viewDidLoad {
        [super viewDidLoad];
     
        [self loadHTMLFile];
    }
     
    - (void)loadHTMLFile {
        NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"demo.html" withExtension:nil];
         
        [self.webView loadRequest:[NSURLRequest requestWithURL:fileURL]];
    }
     
    /**
     要执行 html 中的 js,需要在加载完成之后再执行
      
     stringByEvaluatingJavaScriptFromString 方法,是 WebView 中,唯一一个调用 js 的方法
      
     - string 开头,返回 NSString*
     */
    #pragma mark - UIWebViewDelegate
    - (void)webViewDidFinishLoad:(UIWebView *)webView {
         
        // js的弹窗是阻塞式的!
    //    [webView stringByEvaluatingJavaScriptFromString:@"clickme();"];
         
        NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
        NSLog(@"%@", title);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    /**
     应用场景:QQ好友发送文件-直接浏览文件!
     */
    - (void)loadLocalFile {
        NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"iOS 7 Programming Cookbook.pdf" withExtension:nil];
         
        [self.webView loadRequest:[NSURLRequest requestWithURL:fileURL]];
    }

    2.HTML中调用OC的代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    /**
     提示:如果 OC 的代理方法要求返回 BOOL,程序直接返回 YES,通常一切正常,NO就是不工作!
      
     参数
     1. webView
     2. request:加载页面的请求
     3. navigationType: 浏览的类型,例如:在新窗口中打开链接
     */
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
         
        NSLog(@"%@", request.URL.scheme);
         
        // 如果能够拦截到 myfunc:// 协议头,就可以知道是自定义协议调用 oc 方法
        // scheme 协议头
        if ([request.URL.scheme isEqualToString:@"myfunc"]) {
            NSLog(@"自定义协议,准备调用 OC 的方法 %@", request.URL);
             
            // 需要拦截方法名 & 参数
            NSLog(@"%@", request.URL.pathComponents);
             
            // 1. 方法名
            NSString *methodName = request.URL.pathComponents[1];
            // 2. 参数
            NSString *param = request.URL.pathComponents[2];
             
            // 3. 调用方法 - SEL
    //        UIButton *btn = nil;
    //        [btn addTarget:self action:@selector(click) forControlEvents:UIControlEventTouchUpInside];
            SEL func = NSSelectorFromString(methodName);
            // 之所以会有警告,是因为苹果认为这种方式不安全!
            // 判断 self 是否响应方法
            if ([self respondsToSelector:func]) {
                // clang 编译器 警告 压栈,保存当前编译状态
    #pragma clang diagnostic push
                // 忽略 pefromSelector 的风险警告
    #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
                [self performSelector:func withObject:param];
                // 让编译器出栈,恢复之前保存的状态
    #pragma clang diagnostic pop
            else {
                NSLog(@"方法名错误");
            }
             
            return NO;
        }
         
        return YES;
    }

    转自:http://my.oschina.net/u/1590735/blog/493722?fromerr=bS9RAInT

  • 相关阅读:
    在 Borland C++ 及 Visual C++ 环境中使用 STLport (作者:孟岩)
    设置JavaFX-CSS改变TreeView节点图标
    Using MS DataGrid control with ADO
    两个加载fxml文件的方法
    JavaFX中ObservableValue类型
    在 Eclipse 下利用 gradle 构建系统
    JavaFX初探
    深度剖析如何保证缓存与数据库的一致性
    ACID的实现原理
    一颗高度为3的B+树能存多少行数据?
  • 原文地址:https://www.cnblogs.com/idxdm/p/5026356.html
Copyright © 2011-2022 走看看