UIWebView完美解决响应touch问题
http://www.developers-life.com/touchbegantouchend-in-custom-uiwebview.html
网上找了好久好久都没有解决,终于被我找到解决方法了。
一开始重写UIWebView的touch方法,发现确实可以tap了,可是web view里的URL点击却无效了,原来touch即使传给了next responder,也无法再回到UIWebViewDelegate里调用几个delegate函数。
下面的这个方法,既可以点击URL,又可以响应tap,也是通过写一个新的UIWebView的子类来实现的:
PSWebView.h
#import <UIKit/UIKit.h>
@interface PSWebView : UIWebView
@end
PSWebView.m
#import <objc/runtime.h>
#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