处理UIWebview中的触摸

时间:2009-06-13 15:29:13

标签: iphone uiwebview

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

但是webview子类没有处理touch事件。

是否有任何方法可以处理UIWebView子类???

中的触摸事件

10 个答案:

答案 0 :(得分:45)

不需要子类化,只需添加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;
}

答案 1 :(得分:8)

如果您只需要处理手势,同时保持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”,你很高兴...

答案 2 :(得分:7)

您可以将UIView放在UIWebView上,并覆盖touchesDidBegin等,然后将其发送到您的网页浏览。例如:

用户触摸您的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必须通过网络视图。

答案 3 :(得分: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(/* ... */);"];
}

希望这有帮助吗?

答案 4 :(得分:3)

this Apple Developer forum thread中讨论了在UIWebView上处理手势。

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

线程中最重要帖子的copypaste:

  

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

     

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

     

如果您需要成为唯一处理点击的人,则必须将UITapGestureRecognizer作为子类,这样您就可以在UIGestureRecognizerSubclass.h中使用单向覆盖,然后可以从canBePreventedByGestureRecognizer返回NO:当被问到Web视图的时候轻拍手势识别器可以阻止你的。

     

无论如何,我们都知道这一点,并希望将来能够更轻松。

答案 5 :(得分:2)

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

答案 6 :(得分: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

答案 7 :(得分:0)

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

答案 8 :(得分: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];
}

希望有所帮助!

答案 9 :(得分: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';"];
}