2011-11-07 2 views
9

Nella mia applicazione sto utilizzando un UIPageViewController e volevo avere alcuni UIButton al suo interno, un po 'come un menu. Il problema che ho è che quando metto un UIButton (o qualsiasi altro elemento interattivo) vicino ai bordi dello schermo e lo tocco, invece dell'azione UIButton applicata, ciò che succede è che la pagina cambia (perché il tocco sul bordo dello schermo cambia la pagina su UIPageViewController). Mi piacerebbe sapere se c'è un modo per farlo in modo che UIButton abbia una priorità più alta di UIPageViewController in modo che quando tocchi il pulsante, applichi l'azione appropriata invece di cambiare pagina.Interazione UIButton all'interno di UIPageViewController

risposta

6

Sono venuto qui con lo stesso problema. Split link ha la risposta.

Fai il tuo controller della vista radice il delegato di ciascuno dei sistemi di riconoscimento gesto s' il UIPageViewController, quindi evitare che tocchi da essere consegnati se si verificano all'interno di qualsiasi UIControl:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch 
{ 
    return ([touch.view isKindOfClass:[UIControl class]] == NO); 
} 
4

UIPageViewController ha due UIGestureRecognizers. Puoi accedervi tramite la proprietà gestureRecognizers. Determinare quale è UITapGestureRecognizer e quindi utilizzare this. Spero che questo aiuti.

+0

Funziona in IOS6? –

1

commento a queste riga dal codice

self.view.gestureRecognizers = self.pageViewController.gestureRecognizers; 

o utilizzare UIGestureRecognizer come detto da Spalato

Spero che questo vi aiuterà a

0

Ho avuto questo stesso problema, e non era sicuro come gestire i metodi delegati di UIGestureRecognizer. Questo breve esempio presuppone che si sta utilizzando la "Pagina Based Application" tipo di progetto in Xcode 4. Ecco quello che ho fatto:

  • In RootViewController.h, ho fatto in modo di annunciare che RootViewController avrebbe gestito il protocollo UIGestureRecognizerDelegate:

    @interface RootViewController : UIViewController <UIPageViewControllerDelegate, UIGestureRecognizerDelegate> 
    
  • In RootViewController.m, ho assegnato RootViewController come delegato per UITapGestureRecognizer. Questo è fatto alla fine del metodo viewDidLoad. Ho fatto questo iterando su ogni gestureRecognizer per vedere quale era UITapGestureRecognizer.

    NSEnumerator *gestureLoop = [self.view.gestureRecognizers objectEnumerator]; 
    id gestureRecognizer; 
    while (gestureRecognizer = [gestureLoop nextObject]) { 
        if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) { 
         [(UITapGestureRecognizer *)gestureRecognizer setDelegate:self]; 
        } 
    } 
    
  • Infine, ho aggiunto il gestureRecognizer: Metodo shouldReceiveTouch alla parte inferiore del RootViewController.m (Questo è copiato direttamente dal collegamento di Spalato):

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { 
        if ([touch.view isKindOfClass:[UIControl class]]) { 
         // we touched a button, slider, or other UIControl 
         return NO; // ignore the touch 
        } 
        return YES; // handle the touch 
    } 
    
2

Per le persone che vogliono solo copiare/incollare il codice, qui è mio:

// I don't want the tap on borders to change the page 
-(void) desactivatePageChangerGesture { 
    for (UIGestureRecognizer* gestureRecognizer in self.pageViewController.gestureRecognizers) { 
     if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) { 
      gestureRecognizer.enabled = NO; 
     } 
    } 
} 

basta chiamare questa funzione dopo l'UIPageViewControll er creazione.

+0

Ho fatto +1 su questo solo per "Persone a cui piace copiare il codice incolla": D –

0

RISPOSTA VECCHIO: Se il UIPageViewController ha una transitionStyle di UIPageViewControllerTransitionStyleScroll e siete in iOS 6.0+, quindi non è possibile utilizzare il metodo gestureRecognizer:shouldReceiveTouch:, poiché non è possibile impostare il delegato su self su gestureRecognizers poiché pageViewController.gestureRecognizers restituirà zero. Vedi UIPageViewController returns no Gesture Recognizers in iOS 6 per ulteriori informazioni a riguardo.

Se si desidera semplicemente assicurarsi che il proprio UIPageViewController pass lungo il tasto a sfioramento eventi a un UIButton, è possibile utilizzare

for (UIScrollView *view in _pageViewController.view.subviews) { 
    if ([view isKindOfClass:[UIScrollView class]]) { 
     view.delaysContentTouches = NO; 
    } 
} 

se si dispone di un transitionStyle di UIPageViewControllerTransitionStyleScroll e siete in iOS 6.0 e versioni successive.

Vedi this answer sul perché delaysContentTouches = NO è necessario per alcuni casi di un UIButton in un UIScrollView

UPDATE: Dopo aver fatto un po 'più di ricerca sembra che se il problema è che il UIButton click sembra essere chiamato solo a volte, quindi probabilmente si tratta del comportamento desiderato all'interno di UIScrollView. A UIScrollView utilizza la proprietà delaysContentTouches per determinare automaticamente se l'utente stava tentando di scorrere o provare a premere un pulsante all'interno della visualizzazione di scorrimento. Suppongo che è meglio non modificare questo comportamento predefinito a NO in quanto in tal modo si verificherà l'impossibilità di scorrere se il dito dell'utente si trova su un pulsante.

0

Nessuna delle soluzioni qui in cui si intercettano i rilevatori di gesti toccati di UIPageViewController ha funzionato per me. Ho scelto come target iOS 8 e 9.

Che cosa ha funzionato è quello di sostituire le funzioni touchesBegan, touchesCancelled, touchesMoved e touchesEnded nel mio pulsante personalizzato, che è una sottoclasse di UIControl. Quindi invio semplicemente l'evento di controllo .TouchUpInside se il tocco è iniziato e terminato all'interno del frame del mio pulsante personalizzato.

Non ho dovuto fare niente di speciale per il controller di visualizzazione della pagina contenente, o il controller di visualizzazione che contiene il controller di visualizzazione della pagina.