Работает ли UIGestureRecognizer на UIWebView?

Я пытаюсь получить UIGestureRecognizer, работающий с UIWebview, который является подразделением UIScrollView. Это звучит странно, но когда у меня есть numberOfTouchesRequired установленный в 2, срабатывает селектор, но когда numberOfTouchesRequired установлен на один, селектор не numberOfTouchesRequired .

Вот мой код:

 UITapGestureRecognizer *tap1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(select1:)]; tap1.numberOfTouchesRequired = 2; tap1.numberOfTapsRequired = 1; tap1.delegate = self; [self.ans1WebView addGestureRecognizer:tap1]; [tap1 release]; - (void) select1:(UILongPressGestureRecognizer *)sender { //Do Stuff } 

Я подтвердил это, используя образец Apple для UIGestureRecognizer и вставив веб-просмотр в свой баннер. Их кратный код работает повсюду, но внутри области веб-просмотра.

Из того, что я видел, UIWebView плохо работает с другими. Для распознавателей жестов вы можете попробовать вернуть ДА:

 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer; 

Я должен был быть обратно совместим с 3.0, поэтому я закончил работу с обработкой жестов с помощью Javascript внутри UIWebView. Нехорошее решение, но это сработало для моих нужд. Я смог зафиксировать длинную печать на элементе, а также коснуться, промахнуть, ущипнуть и повернуть. Конечно, я использовал только локальный контент.

Редактировать:

Вы можете посмотреть в PhoneGap на примере отправки сообщений делегату UIWebView. В двух словах вы используете document.location = "myscheme:mycommand?myarguments" затем проанализируйте команду и аргументы из этого обратного вызова делегата:

 -(BOOL) webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType { if ( [[[inRequest URL] absoluteString] hasPrefix:@"myscheme:"] ) { //.. parse arguments return NO; } } 

Вы можете увидеть в коде PhoneGap, что они настроили очередь и таймер для отправки сообщений. В зависимости от вашего использования вам может понадобиться сделать то же самое. На эту тему есть другие вопросы.

Вот документация по обработке событий . В моем случае я добавил слушателей событий к document из

 function myloader() { document.addEventListener( 'touchcancel' , touch_cancel , false ); document.addEventListener( 'touchstart' , touch_start , false ); document.addEventListener( 'touchmove' , touch_move , false ); document.addEventListener( 'touchend' , touch_end , false ); }; 

Фактическая обработка событий зависит от ваших потребностей. Каждый обработчик событий получит TouchEvent с атрибутом touch, где каждый элемент является Touch . Вы можете записать время начала и местоположение в обработчик touchstart. Если прикосновения перемещаются на далекие или неправильные промежутки времени, это не долгое касание.

WebKit может попытаться обработать длинное касание, чтобы начать выбор и скопировать. В обработчике событий вы можете использовать event.preventDefault(); чтобы остановить поведение по умолчанию. Я также нашел -webkit-user-select:none css для некоторых вещей.

 var touch = {}; function touch_start( event /*TouchEvent*/ { event.preventDefault(); touch = {}; touch.startX = event.touches.item(0).pageX; touch.startY = event.touches.item(0).pageY; touch.startT = ( new Date() ).getTime(); } 

Это только второй проект, с которым я использовал javascript. Вы можете найти лучшие примеры в другом месте.

Как вы можете видеть, это не быстрый ответ на вашу проблему. Я очень доволен результатами, которые я получил. В html, с которым я работал, не было интерактивных элементов за пределами ссылки или двух.

UIWebView имеет свои собственные личные взгляды, в которых также есть распознаватели жестов. Следовательно, правила приоритета не позволяют любым распознавателям жестов, добавленным в UIWebView, работать должным образом.

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

Смотрите это на форумах Apple dev .

Это несколько хак-иш-решение, но оно работает. UIWebView имеет множество внутренних распознавателей жестов, которых вы обычно не можете получить без использования частного API. Вы получаете их все бесплатно, однако, когда вы реализуете gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: В этот момент вы можете сообщить всем внутренним UITapGestureRecognizers, чтобы они срабатывали только тогда, когда ваш собственный UITapGestureRecognizer потерпел неудачу. Вы делаете это только один раз, а затем удаляете делегата из своего собственного распознавателя жестов. В результате вы можете по-прежнему панорамировать и прокручивать свой webView, но он больше не получит никаких (одиночных) жестов.

 - (void)viewDidLoad { [super viewDidLoad]; UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)]; // view is your UIViewController's view that contains your UIWebView as a subview [self.view addGestureRecognizer:tap]; tap.delegate = self; } - (void)handleTapGesture:(UITapGestureRecognizer *)gestureRecognizer { NSLog(@"tap!"); // this is called after gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: so we can safely remove the delegate here if (gestureRecognizer.delegate) { NSLog(@"Removing delegate..."); gestureRecognizer.delegate = nil; } } - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { if ([otherGestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) { [otherGestureRecognizer requireGestureRecognizerToFail:gestureRecognizer]; NSLog(@"added failure requirement to: %@", otherGestureRecognizer); } return YES; } 

Наслаждайтесь!

У меня была такая же проблема. Это решение работало для меня:

1) Обязательно добавьте протокол в свой интерфейс: UIGestureRecognizerDelegate, например:

 @interface ViewController : UIViewController  

2) Добавьте эту строку кода

 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES } 

3) Жест установки

 UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(nextSlide)]; swipeGesture.numberOfTouchesRequired = 1; swipeGesture.direction = (UISwipeGestureRecognizerDirectionLeft); swipeGesture.cancelsTouchesInView = YES; [swipeGesture setDelegate:self]; [self.view addGestureRecognizer:swipeGesture]; 
 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer { return YES; } 

Другой способ – сделать прозрачную UIButton поверх UIWebView и обработать краны с этой кнопки. В некоторых случаях это может быть хорошим решением.

 UIWebView webView = [UIWebView new]; //... UIButton *transparentButton = [UIButton buttonWithType:UIButtonTypeCustom]; [transparentButton addTarget:self action:@selector(buttonTapped) forControlEvents:(UIControlEventTouchUpInside)]; transparentButton.frame = webView.frame; transparentButton.layer.backgroundColor = [[UIColor clearColor] CGColor]; [self.view transparentButton]; 

Вы также можете найти мой ответ здесь полезным. Это рабочий пример обработки жестов щепотка в javascript UIWebView.

(Вы могли бы передать события обратно в Objective-C, если хотите. См. Мой ответ здесь .)

  • Проверка доступности iPhone
  • Использование аутентификации AFNetworking и HTTP
  • Выясните, кадр UIBarButtonItem в окне?
  • Добавление изображений в кнопки UIActionSheet, как в UIDocumentInteractionController
  • Класс размера для iPad-портрета и ландшафтных режимов
  • Прокрутка двумя пальцами с помощью UIScrollView
  • Как получить разницу во времени в iPhone
  • NSMutableArray addObject не влияет на счет?
  • Полноэкранный UIView со строкой состояния и наложением панели навигации наверху
  • Как читать трассировки стека объектов-c
  • Измените NSEvent для отправки другого ключа, кроме того, который был нажат
  • Interesting Posts

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

    Когда следует использовать конечную косую черту в моем URL?

    MySQL CONVERT_TZ ()

    Как настроить беспроводную сеть как специальную командную строку?

    Мой компьютер не является телефоном – как удалить экран предварительного просмотра Swipey из Gnome 3?

    Обнаружение 7-дюймового и 10-дюймового планшета программно

    Spark / Scala: форвардная заливка с последним наблюдением

    Когда можно использовать глобальную переменную в C?

    Изменение размера маркера в Google maps V3

    Могу ли я использовать свой MacBook Pro в качестве экрана для mac mini

    Дезаминирование гетерогенного массива JSON в ковариантный список с использованием JSON.NET

    Можно ли сделать консоль полным экраном?

    Угловой UI-маршрутизатор – вложенные состояния с несколькими макетами

    Сделать часть текста ярлыка в стиле жирным шрифтом

    Вызов метода Objective-C из функции члена C ++?

    Давайте будем гением компьютера.