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
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);
}
UIPageViewController ha due UIGestureRecognizers. Puoi accedervi tramite la proprietà gestureRecognizers. Determinare quale è UITapGestureRecognizer e quindi utilizzare this. Spero che questo aiuti.
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
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 metodoviewDidLoad
. 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 }
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.
Ho fatto +1 su questo solo per "Persone a cui piace copiare il codice incolla": D –
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.
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.
Funziona in IOS6? –