处理UIWebview中的触摸
我创build了UIWebView
一个子类,并实现了touchesBegan
, touchesMoved
和touchesEnded
方法。
但webview子类不处理touch
事件。
有什么办法来处理UIWebView
子类中的触摸事件?
不需要子类,只需添加一个UITapGestureRecognizer
:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapMethod)]; [tap setNumberOfTapsRequired:1]; // Set your own number here [tap setDelegate:self]; // Add the <UIGestureRecognizerDelegate> protocol [self.myWebView addGestureRecognizer:tap];
在头文件中添加<UIGestureRecognizerDelegate>
协议,并添加这个方法:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES; }
如果您只需要处理手势,并保持其余的UIWebViewfunction不变,则可以inheritanceUIWebView并使用以下策略:
在UIWebView子类的init方法中,添加一个手势识别器,例如:
UISwipeGestureRecognizer * swipeRight = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeGestureRightMethod)]; swipeRight.direction = UISwipeGestureRecognizerDirectionRight; [self addGestureRecognizer:swipeRight]; swipeRight.delegate = self;
然后,将此方法添加到您的类中:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{ return YES; }
添加和处理您指定的select器的类,在这种情况下,“handleSwipeGestureRightMethod”,你很好去…
你可以在你的UIWebView
放置一个UIView
,并覆盖touchesDidBegin
等,然后将它们发送到你的webview。 例如:
用户触摸你的UIView
,引发一个
- (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; }
你的UIView
必须通过webview。
我不确定这是不是你想要的(这不是你要求的,但它可能取决于你的最终游戏是什么),但你可以在UIWebView中解释JavaScript的触摸,并获得JavaScript做
document.location='http://null/'+xCoord+'/'+yCoord; // Null is arbitrary.
然后你可以使用UIWebView的委托方法来捕获
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
如果request.URL.host(或其它)isEqualToString:@“null”采取相关操作(并返回NO而不是YES)。 您甚至可以通过执行以下操作将JS添加到每个页面:
- (void)webViewDidFinishLoad:(UIWebView *)webView { [webView stringByEvaluatingJavaScriptFromString:@"window.ontouchstart=function(/* ... */);"]; }
希望这可以帮助?
在这个苹果开发者论坛主题中讨论了如何在UIWebView上处理手势。
使用这里给出的信息,在大多数情况下或者所有情况下都不需要额外的视图,如前所述,重写UIWebView并不是一种好的方法。
在线程中最重要的postCopypaste:
这是一个已知的问题。 UIWebView有自己的UITapGestureRecognizers,它们在UIWebView本身的私有子视图上。 UIGestureRecognizer优先级定义在视图层次结构中更深的视图中附加的手势将排除在超级视图上的手势,所以Web视图的轻击手势总是会胜过你的。
如果在你的情况下允许你的点击与网页视图的正常点击一起发生,那么最好的解决scheme是实现UIGestureRecognizerDelegate方法gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer,并返回YES用于其他点击手势。 这样你就可以调用你的tap处理程序,web view仍然会被调用。
如果你需要成为唯一一个处理水龙头的人,你必须inheritanceUITapGestureRecognizer,这样你就可以使用UIGestureRecognizerSubclass.h中的单向覆盖,然后你可以从canBePreventedByGestureRecognizer返回NO:当被问及Web视图的轻敲手势识别器可以阻止你的。
无论如何,我们知道这一点,并希望将来能够更轻松。
我刚刚发现,UIWebView检查是否响应- (void)webViewDidNotClick: (id)webBrowserView
select器,一旦点击视图区域(而不是超级参考,或任何其他应特别处理的区域)。 所以你可以用你的处理代码实现这个select器:)
继Unfalkster之后,你可以使用hitTest方法来实现你想要的,但是你不需要子类化UIWindow。 把这个放在你的web view子类中。 你会得到一个编译时间警告,但它确实工作:
- (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]; }
希望有所帮助!
你的意思是你的分类实现不被调用touchesBegan时,touchesMoved和touchesEnded是否被调用?
这听起来像是如何创build对象的一个实例的问题。 我认为需要更多细节。
(采取forms评论)
头文件
#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
我会尝试在UIWindow上覆盖-sendEvent:看看你是否可以拦截这些触摸事件。
如果你想检测自己的水龙头,但禁用UIWebView的水龙头,那么你可以使用我的解决scheme:
-(void)recursivelyDisableTapsOnView:(UIView*)v{ for(UIView* view in v.subviews){ for(UIGestureRecognizer* g in view.gestureRecognizers){ if(g == self.ownTapRecognizer){ continue; } if([g isKindOfClass:[UITapGestureRecognizer class]] || [g isKindOfClass:[UILongPressGestureRecognizer class]] || [g isKindOfClass:NSClassFromString(@"UITapAndAHalfRecognizer")]){ g.enabled = NO; } } [self recursivelyDisableTapsOnView:view]; } } - (void)webViewDidFinishLoad:(UIWebView *)webView{ [self recursivelyDisableTapsOnView:webView]; //disable selection [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"]; // Disable callout [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"]; }