5

A Sketch of my App's View Hierarchytre strati di pan Gesto Recogniser Confusione

mentre lo sviluppo di un app sono venuto contro un problema di avere troppe riconoscitori gesto pan. Il mio primo riconoscitore di gesture di pan si trova sul MainViewController, che è un genitore di RecipeSearchVC. Questo riconoscitore di gesti fa scorrere l'intera vista a sinistra o a destra. Il mio secondo indicatore di riconoscimento di pan in in RecipeSearchParametersVC, che è un genitore di un Page View Controller. Il terzo indicatore di gesture gestuale viene aggiunto a una UIControl Wheel nidificata all'interno di un controller di visualizzazione che è rappresentato da PageViewController.

So che sembra pazzesco e si potrebbe sostenere che questo è un design scadente. Tuttavia, credo che questo abbia funzionato in modo coeso, andrebbe bene.

Quando si tenta di ruotare la ruota viene ruotata per un paio di secondi prima che il gesto è superato sia dal PageViewController o MainViewController. Il più delle volte è il MainViewController che prende il sopravvento. Quali tecniche potrei impiegare per separare chiaramente ciascuno di questi riconoscitori di gesti?

EDIT:

Scuse per la vaghezza della mia descrizione quando si tratta di riconoscitori gesto pan. Il MainViewController ha il proprio UIPanGestureRecpgniser per consentirgli di spostare tutto a sinistra oa destra. RecipeSearchParametersVC ha solo un UIPanGestureRecogniser a causa dell'UIPageViewController che contiene. Non aggiunge il riconoscitore di gesti stesso, ma semplicemente li prende dalla paginaViewController. I riconoscitori di gesti di UIControl consentono di tenere traccia della rotazione a cui deve essere sottoposto.

Nel prendere il consiglio dato, posso rimuovere i gesti dal controller di visualizzazione della pagina e sostituirli con i pulsanti. Intendevo solo che funzionasse come le immagini (che possono essere scorse per rivelare più immagini) trovate in iBooks e quindi ho pensato che avrebbe funzionato correttamente.

Codice UIControl UIPanGestureRecogniser

/** 
* sent to the control when a touch related to the given event enters the control’s bounds 
* 
* @param touch      uitouch object that represents a touch on the receiving control during tracking 
* @param event      event object encapsulating the information specific to the user event 
*/ 
- (BOOL)beginTrackingWithTouch:(UITouch *)touch 
        withEvent:(UIEvent *)event 
{ 
    [super beginTrackingWithTouch:touch withEvent:event]; 

    CGPoint touchPoint     = [touch locationInView:self]; 

    // filter out touchs too close to centre of wheel 
    CGFloat magnitudeFromCentre   = [self calculateDistanceFromCentre:touchPoint]; 

    if (magnitudeFromCentre < 40)  return NO; 

    // calculate distance from centre 
    CGFloat deltaX      = touchPoint.x - _container.center.x; 
    CGFloat deltaY      = touchPoint.y - _container.center.y; 

    // calculate the arctangent of the opposite (y axis) over the adjacent (x axis) to get the angle 
    _deltaAngle       = atan2(deltaY, deltaX); 

    _startTransform      = _container.transform; 

    // selection in limbo so set all sector image's to minimum value by changing current one 
    [self getSectorByValue:_currentSector].alpha = kMinimumAlpha; 

    return YES; 
} 
+0

Sei riuscito a risolvere il tuo problema? – rog

risposta

2

Sfortunatamente a causa della natura della gerarchia del mio controller, sono stato costretto a ripensare il design della mia app.

Il MainViewController con UIPanGestureRecogniser è rimasto così com'è. UIPageViewController con UIControl si è spostato su un controller di vista statico separato.

Questo funziona molto meglio ma non è ancora ideale. UIPageViewController ruba qualsiasi panning orizzontale, tuttavia questo probabilmente può essere risolto implementando pulsanti in alternativa allo scorrimento.

UIControl non dispone di un riconoscitore di gesti, ma ho eseguito l'override di beginTrackingWithTouch: e altri metodi per tenere traccia dei tocchi.

Suppongo che la risposta dovrebbe essere: se stai stratificando troppi gesti, stai sbagliando.

0

Sarà necessario aggiungere un contenitore per la ruota, e allora si può fare una cosa del genere, se non mi manca qualcosa, questo codice deve funzionare.

UIPanGestureRecognizer* pan1 = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan1:)]; 
[self.view addGestureRecognizer:pan1]; 
UIPanGestureRecognizer* pan2 = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan2:)]; 
[view2 addGestureRecognizer:pan2]; 
UIPanGestureRecognizer* pan3 = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan3:)]; 
[view3 addGestureRecognizer:pan3]; 

- (void) pan1:(UIPanGestureRecognizer*)sender{ 
    NSLog(@"%@",sender); 
} 

- (void) pan2:(UIPanGestureRecognizer*)sender{ 
    NSLog(@"%@",sender); 
} 

- (void) pan3:(UIPanGestureRecognizer*)sender{ 
    NSLog(@"%@",sender); 
} 
0

credo che avrebbe definito 3 diverse UIPanGesture oggetti e attaccato agli viste appropriate.

Mentre tecnicamente questo è corretto potrebbe causare una certa confusione, ad esempio, se si stanno avendo più visualizzazioni sovrapposte (si hanno 3 qui) e bisogno di un tocco per essere inviato a una vista che non è nella parte superiore della vista impilare cosa succederebbe? Il gesto potrebbe finire per essere confuso.

Invece, è possibile allegare un singolo gesto di riconoscimento alla vista suprema di più viste di destinazione e delegare il gesto alla vista corretta in base alle coordinate di dove l'utente sta toccando. Per questo è necessario normalizzare le coordinate di tocco provenienti da una qualsiasi delle sottoview alla superview in cui è definito lo UIPanGesture. In questo modo puoi sapere dove è successo il pan sulla ruota o altrove.

PS: Detto questo, sento fortemente che questo è un trucchetto di design e ti farà male.Ho fatto cose del genere ma alla fine ti imbatterai in un caso in cui l'interazione dell'utente sarebbe stata orribile. Se questa è la vista principale della tua app ti suggerisco di ripensare il design.

0

Quali tecniche posso impiegare per separare chiaramente ciascuno di questi riconoscitori di gesti?

Si dovrebbe esaminare il metodo UIGestureRecognizerDelegate:

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

chiede il delegato se due di riconoscimento gesto dovrebbe essere consentito di riconoscere gesti contemporaneamente.

Questo metodo viene chiamato quando il riconoscimento di un gesto da parte di gestureRecognizer o altroGestureRecognizer bloccherebbe l'altro riconoscimento di gesture dal riconoscere il suo gesto. Si noti che restituire YES è garantito per consentire il riconoscimento simultaneo; restituire NO, d'altra parte, non è garantito per impedire il riconoscimento simultaneo perché il delegato di altri gesture riconoscitore può restituire SÌ.

Credo che questo risolva il tuo problema di gesti "superati" da altri gesti.

Problemi correlati