- 浏览: 171728 次
- 性别:
- 来自: 济南
最新评论
-
enefry:
如果 请求头是 range bytes=100-100 怎么 ...
[JSP]断点续传多线程链接下载! JSP/Servlet 实现 -
zhw332548183:
请问楼主,为什么 图片截取完毕后,会一直显示 正在保存 ...
从android系统图库中取图片的代码 -
zhw332548183:
请问楼主,为什么 图片截取完毕后,会一直显示 正在保存 ...
从android系统图库中取图片的代码 -
lovebirdegg:
82934162 写道lovebirdegg 写道829341 ...
怎样将xmppframework应用于iphone应用程序开发 -
82934162:
lovebirdegg 写道82934162 写道请问,你现在 ...
怎样将xmppframework应用于iphone应用程序开发
For an IPhone app I have been building, I decided to use the UIWebView to render SVG files, instead of doing the vector rendering myself. I needed to have a way to read-in files generated from a vector authoring tool (Illustrator etc.) and after initially looking for an open-source SVG parsing/rendering engine of some sort, I decided on hosting the UIWebView itself instead and use the SVG rendering capability of WebKit. Another option could have been to read in PDF files as PDF is the default meta-file format for Quartz, but I needed programmatic access to each path drawn in the file and it was not apparent to me how I can do that once the PDF is rendered. (Any ideas on that is still welcome of course)
Anyways the point of this post is not really about different options for persisting and reading vector graphic files. I am rather planning to talk a bit about some of the tricky things I found out while trying to use the UIWebView programatically.
Loading the SVG file from your resources folder
This one is quite straightforward. You need to get the correct path for your resources folder and the SVG file in that folder, which can be easily accomplished using the below snippet:
NSString * filePath = [ [ NSBundle mainBundle] pathForResource: @ "filenameWithoutExtension" ofType: @ "svg" ; NSData * svgData = [ NSData dataWithContentsOfFile: filePath] ;
I also wanted to reference the javascript I used in the SVG file, instead of inline embedding. So I made sure that I set the baseURL correctly for the UIWebView to resolve the path to the javascript file in my resources directory:
NSString * resourcePath = [ [ NSBundle mainBundle] resourcePath] ; NSURL * baseURL = [ [ NSURL alloc] initFileURLWithPath: resourcePath isDirectory: YES ] ; [ self.webView loadData: svgData MIMEType: @ "image/svg+xml" textEncodingName: @ "UTF-8" baseURL: baseURL] ; [ baseURL release] ;
However to my surprise the above did not work for locating my script file in the SVG referenced as below:
<script type="text/ecmascript" src="foo.js"/>
Well it turns out the src attribute is not actually in the SVG 1.1 specification at all?? The way I solved that problem is to write a build script to embed the script inline to the svg file (i.e. a preprocessing step) and make it part of the build process. (More on that in a later post…)
UIWebView loading contents when it is off-screen
Another surprise was trying to be able to load the SVG file when the UIWebView was off-screen. My design hosted the UIWebView inside a UIScrollView and I was loading the current page and caching the next and previous pages to have a smooth transition as I swipe the scrollview. But it turns out UIWebView has an issue with loading when it is off-screen. I.e. it does not render its contents, when it comes back into screen unless you double tap into it. It sounds more like a bug to me.
To solve this problem, I delayed the actual loading of the SVG file till:
- ( void ) scrollViewDidEndDecelerating: ( UIScrollView * ) scrollView
for the current view that is becoming visible and I also made sure that once it is loaded when the UIWebView is visible, I don’t ask it to reload it every time the user swipes the view to left and right.
Calling a javascript function from Objective-C
Part of my application is implemented in Javascript and using the DOM to manipulate the SVG document. I need to be able to call some of my Javascript functions from my Objective-C code. This is fairly straightforward and well documented in the UIWebView reference documentation in the SDK. All you need to do is to create an NSString which contains the Javascript function call, and ask the UIWebView to execute it as shown below:
NSString * jsCommand = [ NSString stringWithFormat: @ "setActiveColor(%d, %d, %d);" , redColor, greenColor, blueColor] ; [ self.webView stringByEvaluatingJavaScriptFromString: jsCommand] ;
Javascript communicating back with Objective-C code
What happens when you need to call back your Objective-C code from Javascript? Unfortunately at the time of this writing, there is no proper API for this for the IPhone. (See Apple Documentation for how to do it in MacOS X using WebKit) Fortunately there is a hack, a lot of projects have been using. It basically involves communication through a custom protocol that you make up to pass some parameters and then parsing those parameters in your Objective C code to call your corresponding Objective-C methods.
Basically you create a protocol like below:
myapp: myfunction: myparam1: myparam2
And then in Javascript:
document.location = "myapp:" + "myfunction:" + param1 + ":" + param2;
Then back in your Objective-C code:
- ( BOOL ) webView: ( UIWebView * ) webView2 shouldStartLoadWithRequest: ( NSURLRequest * ) request navigationType: ( UIWebViewNavigationType) navigationType { NSString * requestString = [ [ request URL] absoluteString] ; NSArray * components = [ requestString componentsSeparatedByString: @ ":" ] ; if ( [ components count] > 1 && [ ( NSString * ) [ components objectAtIndex: 0 ] isEqualToString: @ "myapp" ] ) { if ( [ ( NSString * ) [ components objectAtIndex: 1 ] isEqualToString: @ "myfunction" ] ) { NSLog( [ components objectAtIndex: 2 ] ) ; // param1 NSLog( [ components objectAtIndex: 3 ] ) ; // param2 // Call your method in Objective-C method using the above... } return NO ; } return YES ; // Return YES to make sure regular navigation works as expected. }
Hacky: yes. Gets the job done: yes
Disabling the selection flash
Once you do the above steps, you are basically mostly on your way to have a functioning application that makes use of UIWebView as a component. But as any good IPhone application, you need to add more polish and get rid of the user annoyances.
The first annoyance is, what happens when you tap inside the UIWebView control that is hosting an SVG file. There is a default behavior that happens for all image files, including SVG files. The background of the image (including the border area) flashes quickly to some default grayish color.
Turns out there is a way to turn this off through the use of the WebKit CSS property -webkit-tap-highlight-color, and setting the alpha of the color to 0, in my Javascript code does the trick:
document.documentElement .style .webkitTapHighlightColor = "rgba(0,0,0,0)" ;
Disabling the “action” pop-up
The second thing I needed to disable is the “action” popup that appears if you tap and hold the contents of the UIWebView for a few seconds. This is also controlled through a CSS property called -webkit-touch-callout, and setting that to “none” in this case does the trick:
document.documentElement .style .webkitTouchCallout = "none" ;
Disabling default zoom effect
The final user annoyance I had was the zooming effect that happens by default, when you double tap the content area. Well for many applications this may be a desired effect, but in my case, I needed to disable the zooming. I was hoping that there is another CSS property that is something like webkit-disable-doubletap-zoom but unfortunately no such property exists (at least as of this writing.)
The only other idea I came up with was to be able to detect double tapping and calling the standard preventDefault on the event when that touch happens in my Javascript code. But it turns out that SVG DOM does not at the moment fully implement the touch and gesture events . You should be able to use those when you are hosting regular HTML though.
The final approach I came up with was to be able to intercept the touch events before they even reach UIWebView and stop them in my Objective-C code. To do this, you need to read a bit more about how the touch events are routed in Cocoa . (Requires login to the IPhone Dev Center) Basically the idea is to override the hit testing part of the UIWebView and detect the double tap there. In order to that I subclassed UIWebView and overrode the hitTest method in my implementation. Other than that I keep it up the superclass to do the rest.
- ( UIView * ) hitTest: ( CGPoint) point withEvent: ( UIEvent * ) event { NSSet * touches = [ event allTouches] ; BOOL forwardToSuper = YES ; for ( UITouch * touch in touches) { if ( [ touch tapCount] >= 2 ) { // prevent this forwardToSuper = NO ; } } if ( forwardToSuper) { //return self.superview; return [ super hitTest: point withEvent: event] ; } else { // Return the superview as the hit and prevent // UIWebView receiving double or more taps return self.superview; } }
So this finally did the trick and I was able to prevent the double tap zooming effect as well.
发表评论
-
Key-Value Coding. Key-Vaule Observing
2012-02-17 11:41 1260Key-value coding (KVC) 是 ... -
FMDB:我的SQLite救星
2011-08-23 17:08 1306FMDB:我的SQLite救 ... -
统计代码行数
2011-01-04 16:39 2453http://lovebirdegg.appspot. ... -
Universal Static Libraries
2010-04-16 17:02 1121For some reason Apple reserves ... -
《iPhone应用程序开发指南(基础篇)》第六章 6.2(3)
2010-04-16 15:25 1282原文地址:http://www.aisidechina.com ... -
《iPhone应用程序开发指南(基础篇)》第六章 6.2(2)
2010-04-16 15:22 1783原文地址:http://www.aisidechina.com ... -
《iPhone应用程序开发指南(基础篇)》第六章 6.1
2010-04-14 10:27 1752原文地址:http://www.aisid ... -
《iPhone应用程序开发指南(基础篇)》第六章 6.2(1)
2010-04-14 10:25 985原文地址:http://www.aisidechina.com ... -
《iPhone应用程序开发指南(基础篇)》第三章 3.4
2010-04-12 17:16 1173原文地址:http://www.aisid ... -
《iPhone应用程序开发指南(基础篇)》第三章 3.3
2010-04-08 08:10 1398《iPhone应用程序开发 ... -
《iPhone应用程序开发指南(基础篇)》第三章 3.2
2010-04-08 08:09 1423原文地址: http://www.aisidechina. ... -
how to use TouchXML
2010-03-25 21:50 1648iphoen do not have NSXML* libra ... -
《iPhone应用程序开发指南(基础篇)》第三章 3.1
2010-03-25 12:57 1102原文地址:http://www.aisidechina.com ... -
10 个在app store中需要避免的错误(一)
2010-03-19 18:13 1549原文 #1 Creating an Overly Compl ... -
Filtering Fun with Predicate
2010-03-16 09:34 1522原文:http://lovebirdegg.co.tv/201 ... -
《iPhone应用程序开发指南》第一章 1.1(2)
2010-03-12 17:12 2941原文地址: http://www.aisidechina. ... -
《iPhone应用程序开发指南》第一章 1.1(1)
2010-03-12 17:11 2221原文地址: http://www.aisidechina. ... -
《iPhone应用程序开发指南》目录
2010-03-12 17:09 2175原文地址 http://www.ais ... -
《iPhone应用程序开发指南》介绍
2010-03-12 17:07 2800原文地址 http://www.ais ... -
14 open source iphone app store apps
2010-03-10 20:34 1567http://lovebirdegg.co.tv/2010 ...
相关推荐
之前提到UIWebView使用一个UIScrollView对象来关联web页面的内容,通过UIWebView的scrollView属性即可获得该对象,默认情况下网页长度超出设备视口长度后页面会滚动,用户使用手指滚动页面到页面边距并放开手指后...
UIWebView+html+css,实现UIWebView中可点击链接,并且可显示gif动画效果
UIWebView和js交互 里边自己写了个H5方便大家理解
UIWebView Web 网页 Demo 代码
IOS开发中因为引入cocos2dx,导致代码审核不通过无法提交( Apple will stop accepting submissions of apps that use UIWebView APIs )。该问题的解决方案有两种:1)升级Cocos2dx的版本,在查看Cocoas官网及Cocoas...
使用UIWebView和JS进行交互,可以OC操作js,也可以JS对OC进行交互
这是我在学习ios的过程中写的一个demo,使用UIWebView实现一个简单的浏览器
网页视图的基本使用,网络资源地址字符串的处理,UIWebView属性与协议的综合使用;
UIWebView原生与H5交互,pre;confirm;等包含三个H5页面跳转的交互demo
UIWebView实现图文混排
这是iPhone开发之UIWebView示例程序,具体参考: http://blog.csdn.net/htttw/article/details/7888557
UIWebView与JS交互小例子,其中涉及APP向JS提交信息,和JS提交信息给App
ITMS-90809: Deprecated API Usage - New apps that use UIWebView are no longer accepted. Instead, use WKWebView for improved security and reliability. Unity IOS审核被拒,解决办法,去网上看了好多帖子,...
iOS UIWebView URL拦截.pdf
UIWebVeiw的使用,功能包括“返回上页”“在safari打开”“网页刷新”
完美的webView,不懂UIwebView的可以看看
(OC)(UIWebView)新闻详情
IOS自定义请求uiwebview的loading框 支持文字和转圈特效同时存在 动态显示 调用方便
适合对webview的学习 源码 欢迎下载学习
UIWebview使用中的js交互简单的简析 欢迎大家指点 共同学习