Home » iPhone » touchBegan/touchEnd in custom UIWebView

touchBegan/touchEnd in custom UIWebView

The main disadvantage in the object UIWebView is lack of methods touchBegan and touchEnd. But this question has been settled by some manipulations with privates possibilities:) Thank you Satoshi Nakagawa :)

PSWebView.h – empty

1
2
3
4
#import

@interface PSWebView : UIWebView
@end

If you need add method touchBegan then make step by step
1. add after 6 line

1
- (void)webView:(UIWebView*)sender tappedBeganWithTouch:(UITouch*)touch event:(UIEvent*)event;

2. after 11

1
- (void)fireBeganTappedWithTouch:(UITouch*)touch event:(UIEvent*)event;

3. add after 31

1
2
3
4
5
6
7
8
9
10
11
- (void)__touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
     [self __touchesBegan:touches withEvent:event];
     
     id webView = [[self superview] superview];
     if (touches.count == 1) {
          if ([webView respondsToSelector:@selector(fireBeganTappedWithTouch:event:)]) {
               [webView fireBeganTappedWithTouch:[touches anyObject] event:event];
          }
     }
}

4. after 46

1
2
3
     Method targetMethod2 = class_getInstanceMethod(klass, @selector(touchesBegan:withEvent:));
     Method newMethod2 = class_getInstanceMethod(klass, @selector(__touchesBegan:withEvent:));
     method_exchangeImplementations(targetMethod2, newMethod2);

5. and last addition in source before last “@end”

1
2
3
4
5
6
- (void)fireBeganTappedWithTouch:(UITouch*)touch event:(UIEvent*)event
{
     if ([self.delegate respondsToSelector:@selector(webView:tappedBeganWithTouch:event:)]) {
          [(NSObject*)self.delegate webView:self tappedBeganWithTouch:touch event:event];
     }
}

For touchMoves similar steps. It’s easy!

PSWebView.m – all implementation in this file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#import
#import "PSWebView.h"

@interface NSObject (UIWebViewTappingDelegate)
- (void)webView:(UIWebView*)sender zoomingEndedWithTouches:(NSSet*)touches event:(UIEvent*)event;
- (void)webView:(UIWebView*)sender tappedWithTouch:(UITouch*)touch event:(UIEvent*)event;
@end

@interface PSWebView (Private)
- (void)fireZoomingEndedWithTouches:(NSSet*)touches event:(UIEvent*)event;
- (void)fireTappedWithTouch:(UITouch*)touch event:(UIEvent*)event;
@end

@implementation UIView (__TapHook)

- (void)__touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
     [self __touchesEnded:touches withEvent:event];
     
     id webView = [[self superview] superview];
     if (touches.count > 1) {
          if ([webView respondsToSelector:@selector(fireZoomingEndedWithTouches:event:)]) {
               [webView fireZoomingEndedWithTouches:touches event:event];
          }
     }
     else {
          if ([webView respondsToSelector:@selector(fireTappedWithTouch:event:)]) {
               [webView fireTappedWithTouch:[touches anyObject] event:event];
          }
     }
}

@end

static BOOL hookInstalled = NO;

static void installHook()
{
     if (hookInstalled) return;
     
     hookInstalled = YES;
     
     Class klass = objc_getClass("UIWebDocumentView");
     Method targetMethod = class_getInstanceMethod(klass, @selector(touchesEnded:withEvent:));
     Method newMethod = class_getInstanceMethod(klass, @selector(__touchesEnded:withEvent:));
     method_exchangeImplementations(targetMethod, newMethod);
     
}

@implementation PSWebView

- (id)initWithCoder:(NSCoder*)coder
{
    if (self = [super initWithCoder:coder]) {
          installHook();
    }
    return self;
}

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

- (void)fireZoomingEndedWithTouches:(NSSet*)touches event:(UIEvent*)event
{
     if ([self.delegate respondsToSelector:@selector(webView:zoomingEndedWithTouches:event:)]) {
          [(NSObject*)self.delegate webView:self zoomingEndedWithTouches:touches event:event];
     }
}

- (void)fireTappedWithTouch:(UITouch*)touch event:(UIEvent*)event
{
     if ([self.delegate respondsToSelector:@selector(webView:tappedWithTouch:event:)]) {
          [(NSObject*)self.delegate webView:self tappedWithTouch:touch event:event];
     }
}

@end

Source

Comments are closed.