簡體   English   中英

處理UIWebview內部的觸摸

[英]Handling touches inside UIWebview

我創建了UIWebView的子類,並實現了touchesBegantouchesMovedtouchesEnded方法。

但是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;
}

如果您只需要處理手勢,而其余的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”,您可以繼續...

您可以將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必須位於網絡視圖上方。

我不確定這是否是您想要的(不是您想要的,但可能取決於您的最終游戲是什么),但您可以改為從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(/* ... */);"];
}

希望這可以幫助?

Apple Developer論壇主題中討論了在UIWebView上處理手勢。

使用此處提供的信息,在大多數或所有情況下都不需要額外的視圖,並且如前所述,覆蓋UIWebView並非可行之路。

線程中最重要的帖子的復制粘貼:

這是一個已知的問題。 UIWebView擁有自己的UITapGestureRecognizer,它們位於UIWebView本身的私有子視圖中。 UIGestureRecognizer優先級定義了附加到視圖層次結構中較深視圖的手勢將排除超級視圖上的手勢,因此Web視圖的輕擊手勢將始終勝過您的手勢。

如果可以的話,允許點擊和Web視圖的正常點擊一起發生,那么最好的解決方案是實現UIGestureRecognizerDelegate方法gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer並為其他點擊手勢返回YES。 這樣,您將調用Tap處理程序,並且Web視圖仍將被調用。

如果您是唯一需要處理輕敲的人,則必須將UITapGestureRecognizer子類化,以便可以使用UIGestureRecognizerSubclass.h中的單向替代,然后您就可以從canBePreventedByGestureRecognizer返回NO:當詢問網絡視圖的輕敲手勢識別器時可以防止你的

無論如何,我們都知道這一點,並希望將來變得更容易。

我剛剛發現,一旦一個人點擊了視圖區域(而不是hyperref或應專門處理的任何其他區域- (void)webViewDidNotClick: (id)webBrowserView ,UIWebView確實會檢查它是否響應- (void)webViewDidNotClick: (id)webBrowserView選擇器。 因此,您可以使用處理代碼來實現該選擇器:)

我會嘗試在UIWindow上覆蓋-sendEvent:,以查看是否可以攔截這些觸摸事件。

按照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];
}

希望有幫助!

如果您想檢測自己的水龍頭但禁用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';"];
}

您是說在調用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM