【iOS】WebView的使用、Javascript和Objective-C的交互

现在的App越来越有直接在一个View中摆个WebView,然后里面镶嵌个HTML5网页,再加些和手机系统联系的方法的趋势了。这样做,以免IOS Apps一套,安卓那边一套,HTML5的手机网页版又一套。我都懒得烦了,一套HTML5代码吃遍天下,反正现在的HTML5网页已经做得以假乱真的底部,用户根本感觉不到,这是用IOS写的,还是HTML5写的。因此,有必要研究iOS中的WebView使用,与镶嵌在iOS工程中的HTML5利用JS和Objective-C的交互。这东西就像,更应该说,“就是”安卓中的《【Android】检测是否处于Wifi环境,利用WebView实现浏览器app》(点击打开链接)。

下面举一个例子来说明这个问题,如图:


如下图所示,我在MainStoryboard.storyboard布置了一个TextField,一个Button,一个Label,这些都是iOS的原生组件,然后拖了一个Web View,Web View中放一个网页。网页布置了段落文字<p>输入框<input type="text" id="text"/>和一个按钮,永远说明WebView中的网页显示与iOS的交互问题。如上图所示,大家可以看到,网页中的内容可以修改iOS的组件的内容,iOS可以控制网页的内容。如同《【ActionScript】Flash与网页的交互,ActionScript与JavaScript的交互》(点击打开链接)一样,两种语言相映成趣。

具体制作如下:

1、如同上图所示一样拖完各个组件之后。对于WebView勾上Scales Page To Fit,避免镶嵌在里面的网页出现水平滚动条,避免出现垂直滚动条,需要未来在代码中实现。


2、然后如同在《【iOS】点击按钮Button,更变标签文字Label的颜色》(点击打开链接)一样,对MainStoryboard.storyboard中各个组件进行注册,注册之后,ViewController.h如下所示,一个Button按钮点击函数,与三个组件的在ViewController.m操纵的id。同时这里,注意在接口中@interface ViewController : UIViewController<UIWebViewDelegate>,添加<UIWebViewDelegate>的委托,以便能够操控WebView。

//
//  ViewController.h
//  WebView
//
//  Created by pc on 17-7-11.
//  Copyright (c) 2017年 pc. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController<UIWebViewDelegate>
@property (weak, nonatomic) IBOutlet UIWebView *webview1;
@property (weak, nonatomic) IBOutlet UITextField *textfield1;
@property (weak, nonatomic) IBOutlet UILabel *label1;
- (IBAction)onclick:(id)sender;

@end
3、打开项目的文件夹,在里面新建一个www文件夹,当然你叫别的名字也可以啊,在下面的代码注意修改就行。


新建之后,以如下图的方式,将这个新建的www文件夹,附着到工程:


在www文件夹中新建一个index.html。


4、在index.html设置如下的代码,当然这段的代码未来将和ViewController.m的代码交相辉映的,可以对照着看。

<!doctype html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=0.8, maximum-scale=0.8, user-scalable=no">
    </head>
    <body>
        <p id="text1">中文是没有问题的!</p>
        <input type="text" id="text"/><br>
        <button οnclick="hello_ios()">发送</button>
    </body>
    <script>
        function hello_js(msg){//接受objective-C传递过来的msg
            document.getElementById("text1").innerHTML=msg;//将上面<p>标签的文本修改了
        }
        function hello_ios(){//传递信息给objective-C
            var text=document.getElementById("text").value;
            window.location="toios://A?content="+text;//将<input type="text" id="text"/>的内容传递过去
            //toios和A是自己定义的“协议”,也就是传递的url,可以自己定义为其它。
        }
    </script>
</html>

5、之后是ViewController.m的代码:

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

/*输入键盘的处理*/
//允许用户点击空白区域关闭键盘
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];
    [self.view endEditing:YES];
}
//允许用户通过点击return键关闭键盘
-(BOOL)textFieldShouldReturn:(UITextField *) textField{
    [textField resignFirstResponder];
    return YES;
}

//初始化的时候所执行的内容
- (void)viewDidLoad
{
    [super viewDidLoad];
    //载入项目工程下www中的index.html
    self.webview1.delegate=self;
    NSString *path=[[NSBundle mainBundle]pathForResource:@"www/index" ofType:@"html"];
    [self.webview1 loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:path]]];
}
//保证WebView不出现垂直滚动条
- (void)webViewDidFinishLoad:(UIWebView *)webView//在网页最终完成加载之后再执行
{
    //获取网页内容的总高度之后,再设置缩放比例
    CGRect frame = webView.frame;
    CGSize fittingSize = [webView sizeThatFits:CGSizeZero];
    frame.size = fittingSize;
    webView.frame = frame;
}
//按钮点击事件,objective-C发信息给javascript
- (IBAction)onclick:(id)sender {
    [self.webview1 stringByEvaluatingJavaScriptFromString:[[NSString alloc]initWithFormat:@"hello_js('%@')",self.textfield1.text]];//实质就是要求WebView中镶嵌的网页执行:@"hello_js(文本框Textfield输入内容)"的这个javascript函数
}
//对javascript传递过来的信息进行响应
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSURL * url = [request URL];
    if ([[url scheme] isEqualToString:@"toios"]) {//这里的url[scheme]实质就是javascript定义的toios
        if([[url host] isEqualToString:@"A"]){//这里的[url host]实质就是javascript定义的A
            NSArray *params =[url.query componentsSeparatedByString:@"&"];//对?也就是协议所代的参数进行拆分
            NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];//用一个数据字典存参数
            for (NSString *paramStr in params){
                NSArray *dicArray = [paramStr componentsSeparatedByString:@"="];
                if (dicArray.count>1){//=的前项是参数名,作为字典的key,后项是参数值,作为这个key对应的值
                    NSString *decodeValue=[dicArray[1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
                    [dictionary setObject:decodeValue forKey:dicArray[0]];
                }
            }
            self.label1.text=[[NSString alloc]initWithFormat:@"js传递过来的内容是:%@",[dictionary objectForKey:@"content"]];//将label1的文本换成content这个参数
        }
        return NO;
    }
    return YES;
}


@end

首先,对于输入键盘的2个处理函数,有textfield就一定要有,不然不符合用户的输入习惯了,这里不再赘述了,具体可以参考《【iOS】基本控件:文本输入框、开关、分段控件、滑块与输入键盘隐藏的问题》( 点击打开链接)。

后半部分的重头戏分为两部分,第一部分是WebView的内容显示和内容调整问题,内容显示设置好需要显示的项目网页即可,之后在网页内容加载完毕,再求出其高度,从而计算缩放比例,以便WebView没有垂直和水平滚动条。还和iOS本身的Apps背景色一样,这样就能瞒天过海,试想,如果在直接在Apps就一个这样的WebView,你完全可以用HTML5来开发iOS,然后当作Apps发布。

之后的Javascript和Objective-C的交互,Objective-C传东西给Javascript就好办,直接利用已经封装好的函数就好了,而Javascript传东西Objective-C,虽然在iOS7之后有新的函数,但为了全iOS通用,还是走Javascript肯定能识别的uri通道。这玩意就是相当于Ajax,也可以理解为Javascript带着一些参数,以get的方式跳转到某个网页。之后Objective-C处理对特定uri通道进行处理,如果你多个动作,还可以在自己用if-else if或者switch定义多个协议的Objective-C动作。可以看到Objective-C处理对特定uri通道进行处理,就是在拆解字符串而已,虽然上面的代码很长,但其实就是不停拆建传过来的字符串,拆到最后我们需要的东西,更新一下label1的内容而已。逻辑很简单,以后使用直接改上面的@文本就好了!

建议index.html的javascirpt代码和ViewController.m最后两个函数对照着看,这样更容易理解!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值