Подтвердить что ты не робот

Обработка штрихов внутри UIWebview

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

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

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

4b9b3361

Ответ 1

Нет необходимости в подклассе, просто добавьте 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;
}

Ответ 2

Если вам нужно только обрабатывать жесты, оставив остальную часть функций 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", и вам хорошо идти...

Ответ 3

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

Ответ 4

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

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

Ответ 5

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

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

Copypaste самого важного сообщения в теме:

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

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

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

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

Ответ 6

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

Ответ 7

Следуя тому, что сказал 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];
}

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

Ответ 8

Вы имеете в виду, что ваша подклассифицированная реализация не вызывается, когда вызывается touchBegan, touchsMoved и 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

Ответ 9

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

Ответ 10

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