Просто сделал быстрый демонстрационный проект, который потребовал управления некоторыми файлами Excel. Компонент.NET из программного обеспечения GemBox был достаточен для моих потребностей. Это имеет бесплатную версию с несколькими ограничениями.
Большинство подходов имеют дело со сложной парой подклассов UIView
и UIWebView
и отменяют -touchesBegan: withEvent:
и т. Д. .. методы.
Этот подход, основанный на JavaScript, перехватывает прикосновения к самой веб-модели DOM, и кажется умным способом обойти более сложный процесс. Сам я не пробовал, но мне любопытно узнать результаты, если вы попробуете.
Я не уверен в точных деталях реализации, но вам нужно создать подкласс UIWindow и переопределить sendEvent :. Затем вы можете захватывать события касания и обрабатывать их соответствующим образом, прежде чем они перейдут в веб-представление. Надеюсь, это укажет вам правильное направление!
Взято из записи в блоге (не загружается, но, к счастью, это Google Cache'd ), автор Митхин Кумар .
(Митхин, я надеюсь, ты не против, чтобы я перепечатал его здесь; если вы это сделаете, дайте мне знать в комментариях, и я удалю его.)
Недавно я работал над проектом, который требовал обнаружения касания и событий в UIWebView. Мы хотели узнать HTML-элемент, на который пользователь нажимает в UIWebView, а затем, в зависимости от нажатого элемента, должно было быть выполнено какое-то действие. После некоторого поиска в Google я обнаружил, что большинство пользователей накладывают прозрачный UIView поверх UIWebView, повторно реализуют сенсорные методы класса UIResponder (например, -touchesBegan: withEvent :) и затем передают события UIWebView. Этот метод подробно описан здесь . Есть несколько проблем с этим методом.
- Копирование / выделение перестает работать в UIWebView
- Нам нужно создать подкласс UIWebView, хотя Apple говорит, что мы не должны подклассифицировать его.
- Множество других функций 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, которую пользователь коснулся.