質問

uiscrollviewのサブビューであるuiwebviewを使用してuigesturerecognizerを使用しようとしています。これは奇妙に聞こえますが、私が持っているとき numberOfTouchesRequired セレクターの火災を2つに設定しますが、いつ numberOfTouchesRequired セレクターが発射しない1つに設定されています。

これが私のコードです:

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サンプルをUigesturerCognizerに使用し、ペン先にWebViewを挿入することでこれを確認しました。タップコードは、WebViewの領域内で至る所で機能します。

役に立ちましたか?

解決

私が見たことから、Uiwebviewは他の人とうまくいきません。ジェスチャー認識者の場合、次のようにyesを返してみてください。

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

私は3.0と後方互換性がなければならなかったので、UIWebview内のJavaScriptを使用してすべてのジェスチャー処理を行うことになりました。良い解決策ではありませんが、私のニーズのために機能しました。要素を長いプレスをキャプチャし、タップ、スワイプ、ピンチ、回転をキャプチャすることができました。もちろん、私はローカルコンテンツのみを使用していました。

編集:

あなたは見ることができます 電話ガップ 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;
  }
}

電話ガップコードで、メッセージを送信するためにキューとタイマーを設定していることがわかります。使用法に応じて、同じことをする必要があるかもしれません。このトピックには他の質問があります。

これが次のとおりです イベント処理 ドキュメンテーション。私の場合、イベントリスナーを追加しました document から <body onload="myloader();">

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 );
};

実際のイベント処理は、ニーズに大きく依存します。各イベントハンドラーはaを受け取ります TouchEvent 各アイテムがaのタッチプロパティで 触る. 。 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を使用した2番目のプロジェクトにすぎません。他の場所でより良い例を見つけることができます。

ご覧のとおり、これはあなたの問題に対する迅速な答えではありません。私が得た結果にかなり満足しています。私が働いていたHTMLには、リンクを超えてインタラクティブな要素がありませんでした。

他のヒント

Uiwebviewには独自のプライベートビューがあり、ジェスチャー認識者も添付されています。したがって、優先順位ルールは、UIWebviewに適切に動作しないように、ジェスチャー認識者を追加します。

1つのオプションは、uigesturerecognizerdelegateプロトコルを実装し、メソッドGestureRecognizerを実装することです。他のタップジェスチャーについては、この方法から「はい」を返します。これにより、タップハンドラーが呼び出されますが、Webビューは引き続き呼び出されます。

見る これはApple Devフォーラムで.

これはややハックっぽいソリューションですが、機能します。 uiwebviewには、プライベートAPIを使用せずに通常アクセスできない内部ジェスチャー認識者がたくさんあります。ただし、実装すると無料で入手できます gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:. 。その時点で、すべての内部UITAPGESTURERECOUGNIASERSが、あなた自身の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 <SlideViewProtocol, UIGestureRecognizerDelegate>

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;
}

もう1つの方法は、透明な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];

あなたも私の答えを見つけるかもしれません ここ 役に立った。これは、uiwebviewのJavaScriptでピンチジェスチャーを処理する実用的な例です。

(必要に応じて、イベントをObjective-Cに伝えることができます。 ここでの私の答え.)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top