我创建了一个 UIWebView
的子类,并实现了 touchesBegan
、touchesMoved
和 touchesEnded
方法。
但是这个 Webview 子类没有处理 touch
事件。
是否有方法可以在 UIWebView
子类中处理触摸事件?
我创建了一个 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;
}
UIGestureRecognizerDelegate
的- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
方法并返回YES
,它才开始工作。 - g_fred如果您只需要处理手势,同时保留其余UIWebView功能,则可以子类化UIWebView并使用以下策略:
在您的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;
}
将您指定的选择器添加到类中,并处理它,例如"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.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[webView stringByEvaluatingJavaScriptFromString:@"window.ontouchstart=function(/* ... */);"];
}
希望这能帮到你?
如何在UIWebView上处理手势,可以参考苹果开发者论坛中的这篇帖子。
根据该帖子提供的信息,在大多数或所有情况下都不需要额外的视图,并且如前所述,重写UIWebView并非解决方法。
以下是该帖子中最重要的帖子:
这是一个已知问题。UIWebView有自己的UITapGestureRecognizers,并且它们位于UIWebView本身的私有子视图上。UIGestureRecognizer的优先级定义为与视图层次结构中更深的视图相关联的手势将排除superviews上的手势,因此Web视图的tap手势将始终胜过您的手势。
如果您的情况允许您允许您的敲击与Web视图的普通敲击同时发生,则最好的解决方案是实现UIGestureRecognizerDelegate方法gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer,并为其他敲击手势返回YES。这样,您将调用您的敲击处理程序,Web视图仍将调用其处理程序。
如果您需要是唯一处理轻拍的人,则必须对UITapGestureRecognizer进行子类化,以便您可以使用UIGestureRecognizerSubclass.h中的单向覆盖,并且当被问及web视图的轻拍手势识别器是否可以防止您的手势时,您可以从canBePreventedByGestureRecognizer:返回NO。
无论如何,我们已经了解到这个问题,并希望未来能更容易解决。
我刚刚发现,在用户点击UIWebView中的视图区域(而不是超链接或其他特定区域)时,UIWebView确实会检查是否响应- (void)webViewDidNotClick: (id)webBrowserView
选择器。因此,你可以使用你的处理代码来实现该选择器 :)
继Unfalkster所说的,您可以使用hitTest方法来实现您想要的效果,但您不必子类化UIWindow。只需将此代码放入您的Web视图子类中即可。您会收到编译时警告,但它确实有效:
- (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];
}
hitTest:withEvent:
方法会返回一个 UIView*
。这是有意忽略掉了吗? - ThomasW你的子类实现在调用touchesBegan、touchesMoved和touchesEnded时没有被调用吗?
这听起来像是你创建对象实例的问题。我认为需要更多的细节。
(摘自评论)
头文件
#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
-(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';"];
}
我会尝试在UIWindow上重写-sendEvent:,看看是否可以拦截这些触摸事件。