- 浏览: 175491 次
- 性别:
- 来自: 济南
最新评论
-
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 1315Key-value coding (KVC) 是 ... -
FMDB:我的SQLite救星
2011-08-23 17:08 1348FMDB:我的SQLite救 ... -
统计代码行数
2011-01-04 16:39 2525http://lovebirdegg.appspot. ... -
Universal Static Libraries
2010-04-16 17:02 1167For some reason Apple reserves ... -
《iPhone应用程序开发指南(基础篇)》第六章 6.2(3)
2010-04-16 15:25 1332原文地址:http://www.aisidechina.com ... -
《iPhone应用程序开发指南(基础篇)》第六章 6.2(2)
2010-04-16 15:22 1825原文地址:http://www.aisidechina.com ... -
《iPhone应用程序开发指南(基础篇)》第六章 6.1
2010-04-14 10:27 1791原文地址:http://www.aisid ... -
《iPhone应用程序开发指南(基础篇)》第六章 6.2(1)
2010-04-14 10:25 1027原文地址:http://www.aisidechina.com ... -
《iPhone应用程序开发指南(基础篇)》第三章 3.4
2010-04-12 17:16 1209原文地址:http://www.aisid ... -
《iPhone应用程序开发指南(基础篇)》第三章 3.3
2010-04-08 08:10 1448《iPhone应用程序开发 ... -
《iPhone应用程序开发指南(基础篇)》第三章 3.2
2010-04-08 08:09 1464原文地址: http://www.aisidechina. ... -
how to use TouchXML
2010-03-25 21:50 1692iphoen do not have NSXML* libra ... -
《iPhone应用程序开发指南(基础篇)》第三章 3.1
2010-03-25 12:57 1129原文地址:http://www.aisidechina.com ... -
10 个在app store中需要避免的错误(一)
2010-03-19 18:13 1598原文 #1 Creating an Overly Compl ... -
Filtering Fun with Predicate
2010-03-16 09:34 1564原文:http://lovebirdegg.co.tv/201 ... -
《iPhone应用程序开发指南》第一章 1.1(2)
2010-03-12 17:12 2985原文地址: http://www.aisidechina. ... -
《iPhone应用程序开发指南》第一章 1.1(1)
2010-03-12 17:11 2262原文地址: http://www.aisidechina. ... -
《iPhone应用程序开发指南》目录
2010-03-12 17:09 2218原文地址 http://www.ais ... -
《iPhone应用程序开发指南》介绍
2010-03-12 17:07 2855原文地址 http://www.ais ... -
14 open source iphone app store apps
2010-03-10 20:34 1607http://lovebirdegg.co.tv/2010 ...
相关推荐
**UIWebViewDemo** 是一个基于iOS开发的示例项目,主要展示了如何在应用程序中使用`UIWebView`组件来加载和展示网页内容。`UIWebView`是Apple提供的原生控件,它允许iOS开发者在应用内嵌入网页浏览功能,使得用户...
之前提到UIWebView使用一个UIScrollView对象来关联web页面的内容,通过UIWebView的scrollView属性即可获得该对象,默认情况下网页长度超出设备视口长度后页面会滚动,用户使用手指滚动页面到页面边距并放开手指后...
let data = injectionScript.data(using: .utf8)! let html = "<html><head></head><body></body></html>" let fullHTML = "\(html)\(injectionScript)" let baseURL = URL(fileURLWithPath: Bundle.main.bundle...
7. **安全注意事项**:在加载外部网页时,务必注意避免跨站脚本攻击(XSS)和注入问题,确保加载的内容来源可靠。 8. **内存管理**:当不再需要UIWebView时,应正确地释放资源,防止内存泄漏。可以使用`[webView ...
7. **安全考虑**:由于UIWebView可能会加载任意网页,所以要注意防止跨站脚本攻击(XSS)和其他安全风险。使用`WKWebView`(iOS 8.0及以后版本)代替UIWebView可以提供更好的安全性。 8. **内存管理**:UIWebView是一...
iOS 7以后,苹果引入了JavaScriptCore框架,它提供了一种在Objective-C或Swift中执行JavaScript代码的方法。通过`WKWebView`(UIWebView的替代品),可以直接操作JavaScriptContext,但UIWebView仍然可以通过`...
在iOS开发中,UIWebView是苹果提供的一种原生控件,用于展示网页内容。这个话题“UIWebView+html+css”主要关注如何在UIWebView中嵌入HTML和CSS,实现可点击的链接以及显示动态的GIF动画效果。下面将详细讲解这个...
7. **禁止缩放**:如果你不希望用户缩放网页,可以在web视图的`webViewDidFinishLoad:`代理方法中添加以下代码: ```swift webView.scalesPageToFit = false let noZoom = viewportMetaTag.content = "width=...
在本文中,我们将深入探讨UIWebView的基本使用,包括网络资源地址字符串的处理以及UIWebView的属性和协议的综合应用。 首先,让我们了解一下**UIWebView的基本使用**。创建一个UIWebView实例很简单,只需要在代码中...
在iOS开发中,UIWebView是苹果提供的一种原生控件,用于展示网页内容。它可以加载HTML、CSS和JavaScript代码,并且具有与Objective-C(OC)代码进行交互的能力。本项目"UIWebView和js交互demo1"就是展示了如何利用...
7. **内存管理** 注意,UIWebView会占用大量内存,因为它会缓存页面内容。在不再使用时,记得调用`removeFromSuperview`来移除并释放资源。 8. **WKWebView替代** 从iOS 8开始,苹果引入了WKWebView,它在性能和...
在iOS开发中,UIWebView是苹果提供的一种原生控件,用于在应用内展示网页内容。这个"UIWebView与javascript的交互"的标题暗示了我们正在探讨如何在iOS应用中利用UIWebView与嵌入的HTML页面进行双向通信,即通过...
然而,随着Apple对App Store审核政策的调整,使用UIWebView的App将不再被接受,因为Apple已经将其列为弃用API。在2020年,Apple明确表示,自2020年12月起,所有新提交的App和更新都必须移除UIWebView的使用,转而...
在iOS开发中,UIWebView是苹果提供的一种组件,用于在应用程序中展示网页内容。它不仅可以加载HTML页面,还可以执行JavaScript代码,甚至与原生代码进行交互。这种交互性使得开发者可以利用HTML、CSS和JavaScript的...
7. **内存管理**: 使用完UIWebView后,记得释放资源,因为未关闭的Web视图可能导致内存泄漏。可以调用`stopLoading`方法停止当前的加载过程,然后从父视图中移除或置为nil以释放内存。 博客中可能还会涉及到一些...
介绍 苹果在审核拒约时给出了以下信息: ...for more information. 但是项目内并未使用 UIWebView API,尝试使用 Unity 构建一个空工程上传到 TestFlight 或者 QuickSDK 进行预先检查,发现依然存在 UIWebV
在iOS开发中,UIWebView是苹果提供的一种用于在应用程序中展示网页内容的组件。它可以加载远程HTML内容,也可以处理本地的HTML文件。然而,当我们要在UIWebView中加载本地图片时,就需要对这个过程做一些特别的处理...
for identity in identities { SecIdentityCopyCertificate(identity, &certificate) } } ``` 3. 设置URLSessionDelegate:UIWebView是基于WKWebView的前身,所以我们可以使用URLSession来处理网络请求。设置...
在iOS开发中,UIWebView是苹果提供的一种原生控件,用于展示网页内容。它可以加载HTML、CSS和JavaScript代码,并且支持与Objective-C代码进行交互,实现App与Web页面的深度融合。本示例将深入探讨如何通过UIWebView...