Обнаружение касаний в UIWebView

Просто сделал быстрый демонстрационный проект, который потребовал управления некоторыми файлами Excel. Компонент.NET из программного обеспечения GemBox был достаточен для моих потребностей. Это имеет бесплатную версию с несколькими ограничениями.

http://www.gemboxsoftware.com/GBSpreadsheet.htm

8
задан pgb 8 September 2009 в 21:12
поделиться

3 ответа

Большинство подходов имеют дело со сложной парой подклассов UIView и UIWebView и отменяют -touchesBegan: withEvent: и т. Д. .. методы.

Этот подход, основанный на JavaScript, перехватывает прикосновения к самой веб-модели DOM, и кажется умным способом обойти более сложный процесс. Сам я не пробовал, но мне любопытно узнать результаты, если вы попробуете.

1
ответ дан 5 December 2019 в 07:35
поделиться

Я не уверен в точных деталях реализации, но вам нужно создать подкласс UIWindow и переопределить sendEvent :. Затем вы можете захватывать события касания и обрабатывать их соответствующим образом, прежде чем они перейдут в веб-представление. Надеюсь, это укажет вам правильное направление!

1
ответ дан 5 December 2019 в 07:35
поделиться

Взято из записи в блоге (не загружается, но, к счастью, это Google Cache'd ), автор Митхин Кумар .

(Митхин, я надеюсь, ты не против, чтобы я перепечатал его здесь; если вы это сделаете, дайте мне знать в комментариях, и я удалю его.)

Недавно я работал над проектом, который требовал обнаружения касания и событий в UIWebView. Мы хотели узнать HTML-элемент, на который пользователь нажимает в UIWebView, а затем, в зависимости от нажатого элемента, должно было быть выполнено какое-то действие. После некоторого поиска в Google я обнаружил, что большинство пользователей накладывают прозрачный UIView поверх UIWebView, повторно реализуют сенсорные методы класса UIResponder (например, -touchesBegan: withEvent :) и затем передают события UIWebView. Этот метод подробно описан здесь . Есть несколько проблем с этим методом.

  1. Копирование / выделение перестает работать в UIWebView
  2. Нам нужно создать подкласс UIWebView, хотя Apple говорит, что мы не должны подклассифицировать его.
  3. Множество других функций UIWebView перестать работать.

В конце концов мы выяснили, что правильный способ реализовать это - подкласс UIWindow и повторная реализация метода -sendEvent :. Вот как вы можете это сделать. Сначала создайте подкласс UIWindow

 #import 
@protocol TapDetectingWindowDelegate
- (void) userDidTapWebView: (id) tapPoint;
@конец
@interface TapDetectingWindow: UIWindow {
 UIView * viewToObserve;
 id  controllerThatObservations;
}
@property (неатомный, сохранить) UIView * viewToObserve;
@property (неатомный, присваивать) id  controllerThatObservations;
@конец

Обратите внимание, что у нас есть переменные, которые сообщают UIView, на каком обнаруживать события и контроллер, который получает событие Информация. Теперь реализуйте этот класс следующим образом

 #import "TapDetectingWindow.h"
@implementation TapDetectingWindow
@synthesize viewToObserve;
@synthesize controllerThatObservations;
- (id) initWithViewToObserver: (UIView *) view andDelegate: (id) delegate {
 if (self == [super init]) {
 self.viewToObserve = просмотр;
 self.controllerThatObserve = делегат;
 }
 вернуть себя;
}
- (void) dealloc {
 [выпуск viewToObserve];
 [супер освобождение];
}
- (void) forwardTap: (id) touch {
 [controllerThatObservations userDidTapWebView: touch];
}
- (void) sendEvent: (UIEvent *) event {
 [супер sendEvent: событие];
 если (viewToObserve == nil || controllerThatObserve == nil)
 возвращение;
 NSSet * touch = [событие allTouches];
 если (touches.count! = 1)
 возвращение;
 UITouch * touch = touches.anyObject;
 если (touch.phase! = UITouchPhaseEnded)
 возвращение;
 if ([touch.view isDescendantOfView: viewToObserve] == НЕТ)
 возвращение;
 CGPoint tapPoint = [коснитесь locationInView: viewToObserve];
 NSLog (@ "TapPoint =% f,% f", tapPoint.x, tapPoint.y);
 NSArray * pointArray = [NSArray arrayWithObjects: [NSString stringWithFormat: @ "% f", tapPoint.x],
 [NSString stringWithFormat: @ "% f", tapPoint.y], nil];
 if (touch.tapCount == 1) {
 [самостоятельно выполнитьSelector: @selector (forwardTap :) withObject: pointArray afterDelay: 0,5];
 }
 else if (touch.tapCount> 1) {
 [NSObject cancelPreviousPerformRequestsWithTarget: самоселектор: @selector (forwardTap :) объект: pointArray];
 }
}
@конец

Реализуйте метод sendEvent указанным выше способом, а затем вы можете отправить верните нужную информацию контроллеру.

Есть несколько вещей, о которых нужно помнить. Убедитесь, что в вашем MainWindow.xib окно имеет тип TapDetectingWindow, а не UIWindow. Только тогда все события пройдут через вышеуказанное повторно реализован метод sendEvent. Кроме того, не забудьте позвонить [super sendEvent: event], а затем делайте все, что хотите.

Теперь вы можете создать свой UIWebView в классе контроллера в следующим образом

 @interface WebViewController: UIViewController  {
 IBOutlet UIWebView * mHtmlViewer; 
 TapDetectingWindow * mWindow;
}
- (недействительно) viewDidLoad {
 [супер viewDidLoad];
 mWindow = (TapDetectingWindow *) [[UIApplication sharedApplication] .windows objectAtIndex: 0];
 mWindow.viewToObserve = mHtmlViewer;
 mWindow.controllerThatObservations = self;
}

Помните, что вам нужно написать метод userDidTapWebView в вашем класс контроллера. Это метод, который вызывается для отправки информацию о событии в класс контроллера. В нашем случае выше мы отправляют точку в UIWebView, которую пользователь коснулся.

8
ответ дан 5 December 2019 в 07:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: