のサブクラスを作成し、およびメソッド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 をサブクラス化し、次の戦略を使用できます。
UIWebView サブクラスの init メソッドで、ジェスチャ認識エンジンを追加します。
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
してから、それらを webview に送信できます。元:
ユーザーがあなた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
はウェブビューの上にいる必要があります。
これがあなたが望むものかどうかはわかりませんが(あなたが求めたものではありませんが、エンドゲームが何であるかによってはうまくいくかもしれません)、代わりにUIWebView内からJavaScriptのタッチを解釈し、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" の場合、関連するアクションを実行します (YES ではなく NO を返します)。次のようにして、各ページに JS を追加することもできます。
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[webView stringByEvaluatingJavaScriptFromString:@"window.ontouchstart=function(/* ... */);"];
}
お役に立てれば?
UIWebView でのジェスチャの処理については、この Apple Developer フォーラム スレッドで説明されています。
そこにある情報を使用すると、ほとんどまたはすべての場合に追加のビューは必要ありません。前述のように、UIWebView をオーバーライドする方法はありません。
スレッド内の最も重要な投稿のコピペ:
これは既知の問題です。UIWebView には独自の UITapGestureRecognizers があり、それらは UIWebView 自体のプライベート サブビューにあります。UIGestureRecognizer の優先順位は、ビュー階層のより深いビューに関連付けられたジェスチャがスーパービューのジェスチャを除外することを定義するため、Web ビューのタップ ジェスチャが常に優先されます。
あなたの場合、Web ビューの通常のタップと一緒にタップを許可しても問題ない場合、最良の解決策は UIGestureRecognizerDelegate メソッドを実装することです。このようにして、タップ ハンドラーが呼び出され、Web ビューも呼び出されます。
タップを処理する唯一の人になる必要がある場合は、UITapGestureRecognizer をサブクラス化して、UIGestureRecognizerSubclass.h で一方向のオーバーライドを使用できるようにする必要があります。これにより、canBePreventedByGestureRecognizer: から NO を返すことができます。あなたを防ぐことができます。
いずれにせよ、私たちはこれについて知っており、将来的にはより簡単になることを願っています.
UIWebView は- (void)webViewDidNotClick: (id)webBrowserView
、ビュー領域 (ハイパー参照ではなく、特に処理する必要がある他の領域) をタップすると、セレクターに応答するかどうかを確認することがわかりました。したがって、そのセレクターを処理コードで実装できます:)
touchesBegan、touchesMoved、touchsEndedが呼び出されたときに、サブクラス化された実装が呼び出されないということですか?
オブジェクトのインスタンスをどのように作成したかという問題のように聞こえます。詳細が必要だと思います。
(コメント形式で取得)
ヘッダーファイル
#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
独自のタップを検出したいが、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';"];
}
-sendEvent: を UIWindow でオーバーライドして、これらのタッチ イベントをインターセプトできるかどうかを確認します。
Unfalkster が言ったことに続いて、hitTest メソッドを使用して目的を達成できますが、UIWindow をサブクラス化する必要はありません。これを Web ビューのサブクラスに入れるだけです。コンパイル時に警告が表示されますが、動作します:
- (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];
}
それが役立つことを願っています!