本文转载至 http://ju.outofmemory.cn/entry/18807

有时候我们在内嵌的webview中希望点击一个链接之后,触发iOS原生事件,而不是webview内页面跳转(因为webview的跳转很生硬,而ajax+js模拟则不如原生segue平滑)。

有时候我们希望在页面内consloe.log('log something')的时候在控制台里看到输出,但手机里没有控制台,所以我们希望可以利用xcode的控制台输出信息。

因为iOS没有提供API让我们直接用html或者js来跟外部交互,所以我们必须用另外一种巧妙的办法来实现这两个功能。这种方法可以满足我们两种需求。

console.log

在html页面中重新定义console.log:

<script>// Debugconsole =newObject();console.log =function(log){variframe =document.createElement("IFRAME");iframe.setAttribute("src","ios-log:#iOS#"+log);document.documentElement.appendChild(iframe);iframe.parentNode.removeChild(iframe);iframe =null;}console.debug =console.log;console.info =console.log;console.warn =console.log;console.error =console.log;</script>

然后在需要捕获的viewController.m中实现协议:

-(BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType{NSString*requestString =[[[request URL]absoluteString]stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];//NSLog(requestString);if([requestString hasPrefix:@"ios-log:"]){NSString*logString =[[requestString componentsSeparatedByString:@":#iOS#"]objectAtIndex:1];NSLog(@"UIWebView console: %@",logString);returnNO;}returnYES;}

当然前提是webView需要把委托设定为当前控制器:

self.webView =[[UIWebViewalloc]initWithFrame:CGRectMake(0.0f,0.0f,self.view.bounds.size.width,self.view.bounds.size.height-44)];self.webView.delegate=self;

原理很简单,我们重新定义了console.log函数,还有console.debugconsole.infoconsole.warnconsole.error。当我们在页面js中调用console.log的时候,就会创建一个iframe发出请求,请求的协议为ios-log:,路径就是我们的log字符串。发出请求之后,迅速把这个iframe清理掉。

这样,在webview中我们发出了一个请求,然后就没了。外部我们用objective-c实现了一个协议,就是webview开始发出请求之前就会调用的函数。在这个函数中我们过滤所有的请求(因为除了ios-log,还有一些“正常”的请求比如http和mailto),当前缀为ios-log的时候,我们就NSLog即可。

if最后的returnNO的意思是该webview的请求被捕获,不再请求(这个实际上不存在的页面)。我们希望一些合法请求(比如http、mailto等)不被捕获,所以最后if外面丢了一个returnYES

利用链接触发场景变换

iOS原生的场景变换叫做segue,xcode为我们内置了几种原生动画,比如导航条总是固定在上面的push,这样页面前后推动的时候,导航条保持不变(当然里面的内容可以变),内容的切换也很流畅。segue还可以在interface builder中设置动画效果,包括全屏翻转或者渐进等。

有一些第三方js库可以让我们在webview中模拟这种场景变换,也就是说用css设计一个导航条放在webview中置顶,然后用js或者css3来模拟push或者flip3d的效果。比如iScroll是模拟顶部和底部固定的,jQtouch(这个要FQ搜索)是模拟push和flip3d效果的。

我强烈反对在原生应用中使用js库来实现场景变换动画,因为非常不流畅、不跟手指、动画效果跟原生不同,还有最后一个原因,我们是可以在webview中触发外部场景变换的,原生的!用html5制作流畅的原生app的关键就是能够方便地调用原生接口的功能或者效果我们都用原生的,而不去用笨拙的方法实现。

webview中的代码:

<ahref="myapp://somepagename">一个按钮</a>

非常简单,myapp这个协议你可以自己随便命名,稍后我们会在objective-c中捕获它。

还是要实现该webview的委托controller的协议方法,如果你已经定义这个方法了(就像上面那个例子),你只需要在方法体里加入方法体里面的内容,否则会提醒你重复定义。

-(BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType{NSURL *url =[request URL];if([[url scheme]isEqualToString:@"myapp"]){NSString*slug =[url path];[selfperformSegueWithIdentifier:@"heroSegue"sender:slug];returnNO;}returnYES;}

另外我在interface builder中已经拖拽了一个新的控制器,在新的控制器跟导航控制器之间,我直接拖了一个segue,命名id为heroSegue,所以这里可以用performSegueWithIdentifier来调用segue。

现在,还是在本controller中,我们实现另一个委托方法:

/** 页面转换时触发*/-(void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender {if([segue.identifier isEqualToString:@"heroSegue"]){NSLog(@"%@",sender);[self.webView stopLoading];YUGHeroDetailViewController*destViewController =segue.destinationViewController;destViewController.heroSlug =(NSString*)sender;}}

也就是说,发生segue变化之前,就会执行这一方法,首先判断identifier是不是等于heroSegue,如果是,自己的webview不再载入,目标控制器(也就是即将切换过去的子页面的控制器)中设置公有属性heroSlug的值。

然后,我们在目标页面的controller的H中定义:

@property(strong)NSString*heroSlug;

最后,在目标页面中,我们定义的congroller中的M能拿到heroSlug这个参数。

NSLog(@"%@",self.heroSlug);

这样就可以了,拿到slug之后,我们实际上就可以调用一个本地页面,带上slug参数,然后通过ajax的方式读取远程页面或者json数据,这个就不属于本文内容了。

如果你是新手,在做上面的这些操作的时候可能会漏掉一两个步骤,编辑器会报错,这时候仔细阅读并校对你的代码。如果实在不行,说明清楚操作和报错信息,再给我留言。

练习题:原生title的好处是它在字符数较短时是居中的,而字符更长一点时会偏右显示,更长一些时显示省略号。那么webview载入一个ajax数据的页面的时候,如何在页面载入成功时,设置原生title?

提示,还是自定义协议。

转载于:https://www.cnblogs.com/Camier-myNiuer/p/4442364.html

使用HTML5构建iOS原生APP(2)相关推荐

  1. 如何用html构建ios应用,使用HTML5构建iOS原生APP

    转自http://ju.outofmemory.cn/entry/18807 有时候我们在内嵌的webview中希望点击一个链接之后,触发iOS原生事件,而不是webview内页面跳转(因为webvi ...

  2. 如何用html构建ios应用,使用HTML5构建iOS原生APP(2)

    有时候我们在内嵌的webview中希望点击一个链接之后,触发iOS原生事件,而不是webview内页面跳转(因为webview的跳转很生硬,而ajax+js模拟则不如原生segue平滑). 有时候我们 ...

  3. 如何用html构建ios应用,使用HTML5构建iOS原生APP(5)

    我的app基本上是由一个原生的navigation controller贯穿全局,然后在每一个scene中都有一个主要的UIWebView作为主要逻辑: - (void)viewDidLoad{ .. ...

  4. 原生 和html5,H5和原生APP对比

    作者:senntyou segmentfault.com/a/1190000016759517 现在移动端 web 应用,很多时候都需要与原生 App的开发技术,目前流行的两种方式,原生和Html5. ...

  5. ios html5上架,iOS原生集成H5+详细流程

    iOS原生集成H5+ 集成方式 独立应用方式集成 Widget方式集成 WebView方式集成 可以打开官方链接: 选择 5+SDK -> 5+SDK集成 -> 平台 下查看集成方式 独立 ...

  6. iOS原生App与H5页面交互 离线缓存 笔记

    //webview每次加载之前都会调用这个方法,利用该代理方法截取JS的href来调用原生的方法- (BOOL)webView:(UIWebView*)webView shouldStartLoadW ...

  7. html5 实现ios原生控件,vue.js实现仿原生ios时间选择组件开发经验

    前言 最近几个月一直在看VUE,然后试着只用原生js+vue实现某些组件. PC端时间选择组件 这是最开始实现的pc上的时间选择,平时移动端也在做,所以就想实现一下移动端的时间选择器,下面分享一下我实 ...

  8. ae制h5文字动画_大杀器Bodymovin和Lottie:把AE动画转换成HTML5/Android/iOS原生动画

    前段时间听部门老大说,Airbnb出了个移动端的动画库Lottie,可以和一个名叫Bodymovin的AE插件结合起来,把在AE上做好的动画导出为json文件,然后以Android/iOS原生动画的形 ...

  9. android 2048 动画,大杀器Bodymovin和Lottie:把AE动画转换成HTML5/Android/iOS原生动画

    前段时间听部门老大说,Airbnb出了个移动端的动画库Lottie,可以和一个名叫Bodymovin的AE插件结合起来,把在AE上做好的动画导出为json文件,然后以Android/iOS原生动画的形 ...

  10. 安卓和iOS原生App开发招聘

    待遇:7000~10000元 岗位职责: 1 .全程参与并负责设计.开发Android.ios平台上应用程序: 2.担任App产品开发任务,可以独立完成App的开发: 3.2年以上android全时开 ...

最新文章

  1. 提高WPF程序性能的几条建议
  2. 开发效率提升15倍!批流融合实时平台在好未来的应用实践
  3. (2021年)IT技术分享社区个人文章汇总(电脑技巧篇)
  4. 萌新向Python数据分析及数据挖掘 第二章 pandas 第二节 Python Language Basics, IPython, and Jupyter Notebooks...
  5. python utc时间如何取整_Python和Pandas:如何在不同的分辨率上取整unix时间戳(utc):1min5min15min30min1d?...
  6. Toad for Oracle Authorization key
  7. lcd开机流程图_LCD1602程序代码及显示流程图
  8. PHP+txt聊天室
  9. 【抓包】Xposed+JustTrustMe关闭SSL证书验证
  10. 打开html自动播放音乐,如何使背景音乐在打开网页时就自动播放
  11. python RGB与LCH互转 算法
  12. Codeforces 刷水记录
  13. MG本地服务器如何改ip
  14. 倚天屠龙记君临天下_战斗系统
  15. IDEA跳至行首行末快捷键
  16. 实现promise.all方法
  17. 春节“年味地图”出炉:烤鸭一飞冲天,成全国人气榜首
  18. 面试06,[长亮科技]()(offer)、[荔枝]()FM(在确定部门和薪资)、[涂鸦智能]()(第一轮电话面半小时,待后续)、华资软件(HR面)、[广州速游]()(已挂)。至于公司怎么样不加以言论。
  19. 计算机键盘光标上下键失灵,输入时使用键盘上下键实现光标上下移动功能
  20. 转:pdf密码破解专题

热门文章

  1. ios开发之获取版本号,部分设备信息
  2. 开发工具Charles for Mac(信息抓取) v4.6.3b1
  3. macOS Big Sur:快速入门的50个使用技巧
  4. 解决webstorm out of memory内存不足问题
  5. xadmin 组件拓展自定义使用
  6. openSUSE Tumbleweed 支持 Linux Kernel 4.20
  7. 服务器双网卡导致的网络故障及解决方案
  8. 《嵌入式设备驱动开发精解》——1.1 本书内容的组织
  9. Composer最近升级后导致无法下载包的问题解决办法
  10. iOS KVO实现方式