views:

6230

answers:

10

Hi all,

I have created a subclass of UIWebView , and have implemented the touchesBegan, touchesMoved and touchesEnded methods.

but the web view subclass is not handling the touche events.

Is there any method to handle the touch events inside the UIWebView subclass ???

Thanks...

A: 

Do you mean your sub-classed implementation is not called when touchesBegan, touchesMoved and touchesEnded are called?

It sounds like a problem with how you've created an instance of the object. More details are required I think.

(taken form comments)

Header File

#import <UIKit/UIKit.h> 

@interface MyWebView : UIWebView { } @end

Implementation File

#import "MyWebView.h" 

@implementation MyWebView 

- (id)initWithFrame:(CGRect)frame { 
    if (self = [super initWithFrame:frame]) { } return self; 
} 

- (void)drawRect:(CGRect)rect { 
    NSLog(@"MyWebView is loaded"); 
} 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
   NSLog(@"touches began"); 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    NSLog(@"Touches ended");     
} 

- (void)dealloc { 
   [super dealloc]; 
} 

@end
rjstelling
#import <UIKit/UIKit.h>@interface MyWebView : UIWebView {}@end#import "MyWebView.h"@implementation MyWebView- (id)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { } return self;}- (void)drawRect:(CGRect)rect { NSLog(@"MyWebView is loaded");}- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ NSLog(@"touches began");}- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ NSLog(@"Touches ended"); }- (void)dealloc { [super dealloc];}@end
Biranchi
Where do you call MyWebView *obj = [[MyWebView alloc] initWithFrame:CGMakeZero];
rjstelling
Can someone with enough karma make this a code block?
Tim Bowen
A: 

can you post your code? be sure to call [super touchesBegan:xxx]; inside the touches method

Hikaru
A: 

I don't understand why you would ever want to override the touch events handled by UIWebView. Your user is going to want to zoom in and zoom out on the website, as well as touch to click hpyerlinks etc. The code you posted above doesn't have any implementation in the touch methods... I think it's important to know what you are trying to accomplish. Overriding touch events in a web view seems like a bad idea to me. Is there another way to accomplish the behavior you are looking for from your app?

Tim Bowen
I don't expect such comments from a developer. "Overriding touch events in a web view seems like a bad idea to me"Watch out for "Stanza" and "Kindle" how they have subclassed/hooked the UIWebView for handling events.
Biranchi
Just looking for more information dude, relax.
Tim Bowen
+2  A: 

I'm not sure if this is what you want (it's not what you asked for, but it might work depending on what your end game is), but you could instead interpret the touches in JavaScript from inside the UIWebView, and get javascript to do

document.location='http://null/'+xCoord+'/'+yCoord; // Null is arbitrary.

Then you can catch that using the UIWebView's delegate method

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

And if the request.URL.host (or whatever it is) isEqualToString:@"null" take the relevant action (and return NO instead of YES). You can even add the JS to each page by doing something like:

- (void)webViewDidFinishLoad:(UIWebView *)webView {
  [webView stringByEvaluatingJavaScriptFromString:@"window.onmousedown=function(/* ... */);"];
}

Hope this helps?

Benjie Gillam
Were you able to make this approach work?
pgb
Yes, though not with window.onmousedown! On touches began perhaps.
Benjie Gillam
This approach does not properly work. It seems only to work with clickable html-items as images and links. It seems to have no effect when clicking on div, p, body, document tags :(
mana
A: 

Look here, i used this, its extend UIWebView, its working for me, its very simple... (its note well explained, but if you just copy the code it works...), it manage all events, and you can actually click over links...

J.P. Illanes
A: 

I would try overriding -sendEvent: on UIWindow, to see if you can intercept those touch events.

Unfalkster
A: 

Following on from what Unfalkster said, you can use the hitTest method to achieve what you want, but you don't have to subclass UIWindow. Just put this in your web view subclass. You will get a compile time warning but it does work:

- (void)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (event.type == UIEventTypeTouches) {

     // get location info
     CGFloat x = point.x;
     CGFloat y = point.y;

     // get touches
     NSSet *touches = [event allTouches];

     // individual touches
     for (UITouch *touch in touches) {

      if (touch.phase == UITouchPhaseBegan) {
       // touches began

      } else if (touch.phase == UITouchPhaseMoved) {

      }

      // etc etc
     }
    }

    // call the super
    [super hitTest:point withEvent:event];
}

Hope that helps!

imnk
That's weird... For some reason [event allTouches] always returns an empty set
MihaiD
+1  A: 

You could put an NSView over your UIWebView, and overide the touchesDidBegin etc, then send them to your webview. Ex:

User touches your NSView, which provokes a - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
// Execute your code then send a touchesBegan to your webview like so: [webView touchesBegan:touches withEvent:event]; return; }

your NSView has to be over the webview.

Alexandre Cassagne
this is an iphone app and its using UIKit framework, i guess NSView is only for developing Mac Apps and is availabel in AppKit Framework.
Biranchi
Sorry I meant UIView
Alexandre Cassagne
I tried this approach and it does not work.
St3fan
Well it works for me
Alexandre Cassagne
+7  A: 

The documentation clearly states that UIWebView is not intended for Sub-Classing. However, you can still detect all the events. This tutorial should help.

Mithin
A: 

I've just found than UIWebView does check whether it responds to

-(void) webViewDidNotClick:(id)webBrowserView

selector, once one taps on the view area (not on hyperref, or any other area that should be handled specifically). So you may implement that selector with your handling code :)

indexless