Я создал подкласс UIWebView
и внедрил
touchesBegan
, touchesMoved
и touchesEnded
.
но подкласс webview не обрабатывает события touch
.
Есть ли какой-либо метод обработки событий касания внутри подкласса UIWebView
???
Я создал подкласс UIWebView
и внедрил
touchesBegan
, touchesMoved
и touchesEnded
.
но подкласс webview не обрабатывает события touch
.
Есть ли какой-либо метод обработки событий касания внутри подкласса UIWebView
???
Нет необходимости в подклассе, просто добавьте 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;
}
Если вам нужно только обрабатывать жесты, оставив остальную часть функций 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", и вам хорошо идти...
Вы можете поместить 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
должен быть над веб-просмотром.
Я не уверен, что это то, что вы хотите (это не то, что вы просили, но оно может работать в зависимости от вашей конечной игры), но вы могли бы вместо этого интерпретировать штрихи в 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(/* ... */);"];
}
Надеюсь, что это поможет?
Обработка жестов в UIWebView обсуждается в этот форум форума разработчиков Apple.
Используя предоставленную здесь информацию, в большинстве случаев или во всех случаях не будет необходимости в дополнительном представлении, и, как упоминалось выше, переопределение UIWebView не подходит.
Copypaste самого важного сообщения в теме:
Это известная проблема. UIWebView имеет свои собственные UITapGestureRecognizers, и они находятся в частном подчинении самого UIWebView. Приоритет UIGestureRecognizer определяет, что жесты, привязанные к представлениям глубже в иерархии представлений, будут исключать их для супервизоров, поэтому жесты перехвата веб-поиска всегда будут побеждать над вами.
Если в вашем случае все в порядке, чтобы ваш кран произошел вместе с веб-просмотром, нормальное нажатие вашего лучшего решения заключалось бы в реализации метода UIGestureRecognizerDelegate gestureRecognizer: shouldRecognizeSimultaneousWithGestureRecognizer и возврата YES для других жестов жесты. Таким образом вы получите вызов обработчика крана, и веб-представление все равно получит его вызов.
Если вам нужно быть единственным, кто обращается к крану, вам придется подклассифицировать UITapGestureRecognizer, чтобы вы могли использовать односторонние переопределения в UIGestureRecognizerSubclass.h, вы можете вернуть NO из canBePreventedByGestureRecognizer: когда его спросят, есть ли веб-представление признак распознавания жестов может предотвратить ваши.
В любом случае мы знаем об этом и надеемся облегчить его в будущем.
Я только что обнаружил, что UIWebView проверяет, реагирует ли он на селектор - (void)webViewDidNotClick: (id)webBrowserView
, как только один отбирает область просмотра (а не гиперрефику или любую другую область, которая должна обрабатываться специально). Таким образом, вы можете реализовать этот селектор с вашим кодом обработки:)
Следуя тому, что сказал 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];
}
Надеюсь, что это поможет!
Вы имеете в виду, что ваша подклассифицированная реализация не вызывается, когда вызывается 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
Я бы попробовал переопределить -sendEvent: в UIWindow, чтобы увидеть, можете ли вы перехватить эти события касания.
Если вы хотите обнаружить свои собственные краны, но отключите краны 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';"];
}