Domanda

Sto tentando di ottenere un UIGestureRecognizer lavorare con un UIWebView che è una visualizzazione secondaria di un UIScrollView. Questo suona strano, ma quando ho il set numberOfTouchesRequired a 2 fuochi selettore, ma quando numberOfTouchesRequired è impostato su uno selettore non scatta.

Ecco il mio codice:

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
}

Ho confermato questo utilizzando l'esempio di Apple per UIGestureRecognizer e l'inserimento di un WebView nella loro pennino. Il loro codice di rubinetto funziona ovunque, ma all'interno dell'area del WebView.

È stato utile?

Soluzione

Da quello che ho visto, UIWebView non gioca bene con gli altri. Per di riconoscimento gesto, si potrebbe provare a tornare SI da:

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

Ho dovuto essere compatibile con 3,0 così ho finito per fare tutta la movimentazione con JavaScript all'interno del UIWebView gesto. Non è una buona soluzione, ma ha funzionato per le mie esigenze. Sono stato in grado di catturare una pressione prolungata su un elemento, così come rubinetto, strisciare, stringere e Ruota. Naturalmente, stavo usando solo contenuto locale.

Modifica:

Si può guardare a PhoneGap per un esempio di invio di messaggi al delegato della UIWebView. In poche parole, si utilizza document.location = "myscheme:mycommand?myarguments" quindi analizzare il comando e gli argomenti da questo delegato di callback:

-(BOOL) webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
  if ( [[[inRequest URL] absoluteString] hasPrefix:@"myscheme:"] ) {
    //.. parse arguments
    return NO;
  }
}

Si può vedere nel codice PhoneGap che hanno istituito una coda e timer per inviare i messaggi. A seconda dell'uso, potrebbe essere necessario fare la stessa cosa. Ci sono altre domande sul SO su questo argomento.

Questa è la gestione degli eventi di documentazione . Nel mio caso ho aggiunto listener di eventi per document da <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 );
};

Il trattamento vero e proprio evento dipende molto dalle vostre esigenze. Ogni gestore di eventi riceverà una TouchEvent con una proprietà tocchi in cui ogni elemento è un tocco . È possibile registrare l'ora di inizio e la posizione nel vostro gestore TouchStart. Se i tocchi spostarsi lontano o un importo errato di tempo passa non è un tocco lungo.

WebKit può cercare di gestire una lunga tocco per iniziare una selezione e copiare. Nel vostro gestore di eventi è possibile utilizzare event.preventDefault(); per fermare il comportamento predefinito. Ho anche trovato la proprietà -webkit-user-select:none css a portata di mano per alcune cose.

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

Questo è solo il secondo progetto ho usato con javascript. Si possono trovare esempi migliori altrove.

Come si può vedere questa non è una rapida risposta al vostro problema. Sono abbastanza soddisfatto dei risultati che ho ottenuto. L'html con cui stavo lavorando avuto nessun elementi interattivi al di là di un link o due.

Altri suggerimenti

UIWebView ha le proprie opinioni personali, che ha anche attaccato di riconoscimento dei gesti. Quindi, regole di precedenza mantenere qualsiasi di riconoscimento gesto aggiunti a un UIWebView di funzionare correttamente.

Una possibilità è quella di implementare il protocollo UIGestureRecognizerDelegate e implementare il metodo gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer. Ritorno SI da questo metodo per altri gesti tap. In questo modo avrai il tuo gestore di rubinetto chiamato, e la vista web sarà ancora ottenere la sua chiamata.

questo sui forum di Apple dev .

Si tratta di una soluzione un po 'hack-ish, ma funziona. UIWebView ha un sacco di sistemi di riconoscimento dei gesti interni che normalmente non possono accedere senza utilizzare API private. È li ottiene gratuitamente, però, quando si implementa gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:. A quel punto, si può dire tutte le UITapGestureRecognizers interne al fuoco solo quando il proprio UITapGestureRecognizer è riuscito. Hai solo farlo una volta e poi rimuovere il delegato dal proprio gesto riconoscitore. Il risultato è che si può ancora pan e scorrere il vostro WebView, ma non riceverà più alcun gesti (singolo) tap.

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

Enjoy!

ho avuto lo stesso problema. Questa soluzione ha funzionato per me:

1) Assicurarsi di aggiungere il protocollo per l'interfaccia: UIGestureRecognizerDelegate ad esempio:

@interface ViewController : UIViewController <SlideViewProtocol, UIGestureRecognizerDelegate>

2) Aggiungere questa riga di codice

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES
}

3) gesto Setup

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

Un altro modo è quello di mettere un UIButton trasparente sopra UIWebView e rubinetti maniglia da questo pulsante. In alcuni casi potrebbe essere una buona soluzione.

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

Si può anche trovare la mia risposta qui utile. E 'un esempio di lavoro di gestire il gesto pizzico in javascript di UIWebView.

(Si potrebbe comunicare gli eventi Torna alla Objective-C se si voleva. Vedi la mia risposta qui .)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top