Обработка прикосновений внутри UIWebview - PullRequest
35 голосов
/ 13 июня 2009

Я создал подкласс UIWebView и реализовал touchesBegan, touchesMoved и touchesEnded методы.

но подкласс webview не обрабатывает события touch.

Есть ли какой-либо метод для обработки событий касания в подклассе UIWebView ???

Ответы [ 10 ]

45 голосов
/ 18 сентября 2012

Подклассы не нужны, просто добавьте 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;
}
8 голосов
/ 20 марта 2012

Если все, что вам нужно, это обрабатывать жесты, оставляя остальную часть функциональности UIWebView нетронутой, вы можете создать подкласс UIWebView и использовать эту стратегию:

в методе init вашего подкласса UIWebView добавьте распознаватель жестов, например ::

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», и вы готовы идти ...

7 голосов
/ 22 ноября 2009

Вы можете поместить 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 должен быть через веб-просмотр.

5 голосов
/ 20 июля 2009

Я не уверен, что это то, что вы хотите (это не то, о чем вы просили, но это может сработать в зависимости от вашей конечной игры), но вместо этого вы можете интерпретировать прикосновения в JavaScript из UIWebView, получить 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(/* ... */);"];
}

Надеюсь, это поможет?

3 голосов
/ 06 июня 2013

Обработка жестов в UIWebView обсуждается в этой ветке форума Apple Developer .

Используя приведенную там информацию, в большинстве или во всех случаях не будет необходимости в дополнительном представлении, и, как упоминалось здесь ранее, переопределение UIWebView не является подходящим способом.

Копия самого важного сообщения в ветке:

Это известная проблема. UIWebView имеет свои собственные UITapGestureRecognizer, и они находятся в частном подпредставлении самого UIWebView. Приоритет UIGestureRecognizer определяет, что жесты, прикрепленные к представлениям, расположенным глубже в иерархии представлений, будут исключать жесты в суперпредставлениях, поэтому жесты веб-представления всегда будут превосходить ваши.

Если в вашем случае все в порядке, чтобы ваш касание происходило вместе с обычным касанием веб-представления, вашим лучшим решением было бы реализовать метод gestRecognizer UIGestureRecognizerDelegate: shouldRecognizeSim одновременноouslyWithGestureRecognizer и вернуть YES для других жестов касания. Таким образом, вы получите вызов вашего обработчика крана, а веб-представление будет по-прежнему вызываться.

Если вам нужно быть единственным, кто обрабатывает касание, вам придется создать подкласс UITapGestureRecognizer, чтобы вы могли использовать односторонние переопределения в UIGestureRecognizerSubclass.h, и затем вы можете вернуть NO из canBePreventedByGestureRecognizer: когда вас спросят, отображается ли веб-представление распознаватель жестов касания может помешать вашему.

В любом случае, мы знаем об этом и надеемся облегчить это в будущем.

2 голосов
/ 05 октября 2010

Я только что обнаружил, что UIWebView проверяет, реагирует ли он на селектор - (void)webViewDidNotClick: (id)webBrowserView, один раз касаясь области просмотра (не гиперреф, или любой другой области, которая должна обрабатываться конкретно). Таким образом, вы можете реализовать этот селектор с вашим кодом обработки:)

0 голосов
/ 12 июля 2013

Если вы хотите обнаружить свои собственные сигналы, но отключить сигналы 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';"];
}
0 голосов
/ 18 ноября 2009

Исходя из сказанного Unfalkster, вы можете использовать метод hitTest для достижения желаемого, но вам не нужно создавать подкласс UIWindow. Просто поместите это в свой подкласс веб-представления. Вы получите предупреждение о времени компиляции, но оно работает:

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

Надеюсь, это поможет!

0 голосов
/ 14 ноября 2009

Я бы попробовал переопределить -sendEvent: в UIWindow, чтобы посмотреть, сможете ли вы перехватить эти сенсорные события.

0 голосов
/ 13 июня 2009

Вы имеете в виду, что ваша подклассовая реализация не вызывается при вызовах 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...