36

我创建了 的子类,UIWebView并实现了 和方法。touchesBegantouchesMovedtouchesEnded

但 webview 子类不处理touch事件。

有什么方法可以处理UIWebView子类中的触摸事件???

4

10 回答 10

46

不需要子类化,只需添加一个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;
}
于 2012-09-18T14:25:40.630 回答
9

如果您只需要处理手势,同时保留 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”,您就可以开始了...

于 2012-03-20T00:57:09.490 回答
7

您可以UIView在您的UIWebView, 并覆盖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 上。

于 2009-11-22T00:26:30.943 回答
5

我不确定这是否是您想要的(这不是您所要求的,但它可能会根据您的最终游戏是什么起作用),但是您可以从 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(/* ... */);"];
}

希望这可以帮助?

于 2009-07-20T19:14:35.750 回答
3

处理 UIWebView 上的手势在这个 Apple Developer forum thread中讨论。

使用那里给出的信息,在大多数或所有情况下都不需要额外的视图,并且如前所述,覆盖 UIWebView 不是要走的路。

复制粘贴线程中最重要的帖子:

这是一个已知的问题。UIWebView 有自己的 UITapGestureRecognizers,它们位于 UIWebView 本身的私有子视图上。UIGestureRecognizer 优先级定义了附加到视图层次结构中较深视图的手势将排除超级视图上的手势,因此 Web 视图的点击手势将始终胜过您的手势。

如果在您的情况下允许您的点击与 Web 视图的正常点击一起发生是可以的,那么您最好的解决方案是实现 UIGestureRecognizerDelegate 方法 gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer 并为其他点击手势返回 YES 。这样,您将调用您的点击处理程序,并且 Web 视图仍将被调用。

如果您需要成为唯一处理点击的人,则必须将 UITapGestureRecognizer 子类化,以便您可以使用 UIGestureRecognizerSubclass.h 中的单向覆盖,然后您可以从 canBePreventedByGestureRecognizer: 返回 NO:当被问及是否 Web 视图的点击手势识别器时可以防止你的。

无论如何,我们都知道这一点,并希望在未来让它变得更容易。

于 2013-06-06T10:18:49.393 回答
2

我刚刚发现 UIWebView 确实会检查它是否响应- (void)webViewDidNotClick: (id)webBrowserView选择器,一旦点击视图区域(不是在 hyperref 上,或任何其他应专门处理的区域)。所以你可以用你的处理代码来实现那个选择器:)

于 2010-10-05T19:41:12.940 回答
0

我会尝试在 UIWindow 上覆盖 -sendEvent: 以查看是否可以拦截这些触摸事件。

于 2009-11-14T08:57:33.520 回答
0

继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];
}

希望有帮助!

于 2009-11-18T11:28:26.867 回答
0

你的意思是当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
于 2009-06-13T15:45:00.127 回答
0

如果您想检测自己的点击但禁用 UIWebView 的点击,那么您可以使用我的解决方案:

-(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';"];
}
于 2013-07-12T18:30:19.163 回答