UIWebView
the past couple of days and am documenting my struggles in hopes that this post may save others some time in the future. I've found a solution to my problem, intercepting single-tap events that occur on a UIWebView
, although the solution doesn't seem to be optimal. But first, a little background to the other approaches I've tried...Subclassing
UIWebView
/Overlaying a Transparent UIView
These approaches are basically the same. In a
UIWebView
subclass or in a transparent UIView
subclass (on top of a UIWebView
), override the UIResponder
methods (touchesBegan:withEvent
, touchesMoved:withEvent
, etc...) and handle the touches accordingly.The catch here for me was that I really wanted the
UIWebView
to behave as it always did for any other events. This would suggest that I just needed to intercept any single-tap events, and afterwards, forward all events to the UIWebView
. However, what you really need to do is forward the events to the UiWebView's
immediate subview, which is an instance of UIScroller
. This solution seemed like it would work until I realized that pinch zoom events no longer worked and they are essential to the application I'm building.Even more frustrating is the fact that all of
UIWebView's
subviews are not part of the public SDK. This fact makes it pretty much impossible to programmatically change how UIWebView
works under the covers.For more information on this approach, see the following thread in the Apple developer forums.
Overriding
UIView hitTest:withEvent
methodAccording to Kerem at CodingVentures, he was able to intercept double-tap events on a
UIWebView
by subclassing and overriding the hitTest:withEvent
method. However, when I implemented this technique, the UIEvent
passed into the method always had an empty set of touches making it impossible to get the tapCount
property on any UITouch
objects. I tried overriding hitTest:withEvent
for other UIView
controls (e.g UIWindow
, UIScrollView
, etc...) all with the same result.My Solution
The solution I came up with was to subclass
UIWindow
and override the sendEvent:
method. This method gets called after hitTest:sendEvent
returns but before any of the UIResponder
methods get called. At this point, the UIEvent
contains all of the associated touches, allowing me to access the tapCount
property of the associated UITouch
objects.This solution isn't perfect as I am now handling single-taps at the window level instead of just those that occur on the
UIWebView
. Luckily, this doesn't really interfere with what I'm trying to do in my application.I'd still really like to know why it seems that someimes the
UIEvent
passed into hitTest:sendEvent
has touches associated with it and sometimes doesn't. I'd also be interested if anyone can successfully forward on pinch events to UIWebView
.
9 comments:
Did you get it to work.
I have been trying to get 3 buttons to launch different webpages.
Thanks
Florence
Can you explain your method in more details?
How to use the subclassed UIWindow? What is the relation between subclassed UIWindow and the UIWebView?
I try to use the subclassed UIWindow in the Application Delegate class, but it seems that it never gets called.
The class is just a subclass of UIWindow. The app delegate class has a member variable of the subclassed window. Did you remember to change the class of the window to your subclass in Interface Builder?
For an alternative way to receive touch events from a UIWebView see: http://iPhoneIncubator.com/blog/windows-views/360idev-iphone-developers-conference-presentation
There's also an example of how to handle pinch events in the presentation and in the sample code.
Hi Ryan,
Thanks for the sharing. I encounter similar problem when I want to program an UIView to intercept all multi-touch events (only forward single touch). It appears to be simple and straightforward. I read through the documentation on "Event Handling" in iPhone Application programming guide. It didn't say it's not that straightforward at all...
Anyway... here's some further reference I found in Apple's developer forum which are pretty useful:
Forward Touches to a WebView
Touch inside intersection of two UIView
I am subclassing MainWindow with UIWindow and in that using
hit test method:
-(UIView *)hitTestCGPoint)point withEventUIEvent *)event {
UIView *hitView = [super hitTestoint withEvent:event];
if (hitView == self)
return [[self subviews] lastObject];
else if([hitView isDescendantOfView:myView])
{
NSSet *touches = [event allTouches];
if ([touches count] >= 2) {
// prevent this
NSLog(@"Count =2");
return [[self subviews] lastObject];
}
}
return hitView;
}
But I am getting touches as zero object.
I debugged and checked event is always having 0 object.
But responder is having details of the events .
why is like that and how should I get the tap count
Any help??
I try to do what yodark spoke, but I have difficulty doing so. when I run, it displays the application that created, but not in the view tab strip I linked.
Hi Ryan, i have try your suggestion, and then, amazing, the touches event can forward into the webview.
Thank you very much.
But in my project i have a problem, i didn't want to set a pinch gesture, and i didn't do it. But when i try pinch my app in device or touch it using 2 fingers, the app got crashed. Can you help me to solved it??
Thanks Ryan, I appreciate your guidance. The touches event forwards to the webview and everything else is working accordingly.
Post a Comment