5

A Sketch of my App's View Hierarchydrei Ebenen der Pan Geste Recogniser Verwirrung

Während eine App Entwicklung Ich habe mit zu viele pan Geste recognisers gegen ein Problem kommen. Mein erster Pan-Gesten-Erkenner befindet sich auf dem MainViewController, der ein Elternteil der RecipeSearchVC ist. Dieser Gestenerkenner verschiebt die gesamte Ansicht nach links oder rechts. Meine zweite Pan-Gesten-Erkennung in der RecipeSearchParametersVC, die ein Elternteil eines Page View-Controllers ist. Die dritte Gestenerkennung für Schwenkgeste wird einem UIControl-Rad hinzugefügt, das in einem Ansichtscontroller verschachtelt ist, der durch den PageViewController dargestellt wird.

Ich weiß, das klingt verrückt und es könnte argumentiert werden, dass dies ein schlechtes Design ist. Ich glaube jedoch, dass dies in kohäsiver Weise funktioniert, wäre in Ordnung.

Wenn Sie versuchen, das Rad zu drehen, wird es für eine oder zwei Sekunden gedreht, bevor die Geste entweder vom PageViewController oder vom MainViewController übernommen wird. Meistens übernimmt der MainViewController die Kontrolle. Welche Techniken könnte ich anwenden, um jeden dieser Gestenerkenner eindeutig zu trennen?

EDIT:

Apologies für die Unbestimmtheit meiner Beschreibung, wenn es um die Pfanne Geste recognisers kommt. Der MainViewController hat seinen eigenen UIPanGestureRecpgniser, damit er alles nach links oder rechts verschieben kann. Der RecipeSearchParametersVC hat nur einen UIPanGestureRecogniser, weil er UIPageViewController enthält. Es fügt den Gestenerkenner nicht selbst hinzu, sondern nimmt sie einfach vom pageViewController. Die Gestenerkenner von UIControl ermöglichen es, die Rotation, der sie unterzogen werden soll, zu verfolgen.

In Anbetracht der gegebenen Ratschläge kann ich die Gesten aus dem Seitenaufruf-Controller entfernen und sie mit Schaltflächen ersetzen. Ich wollte nur, dass dies so funktioniert wie die Bilder (die man scrollen kann, um mehr Bilder zu entdecken), die man in iBooks findet, und so dachte ich, dass es gut funktionieren würde.

UIControl UIPanGestureRecogniser-Code

/** 
* 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

Konnten Sie Ihr Problem lösen? – rog

Antwort

2

Leider war ich aufgrund der Art meiner Controller-Hierarchie gezwungen, das Design meiner App zu überdenken.

Der MainViewController mit dem UIPanGestureRecogniser ist so geblieben wie er ist. Der UIPageViewController mit dem UIControl wurde in einen separaten statischen Ansichtscontroller verschoben.

Dies funktioniert viel besser, ist aber noch nicht ideal. Der UIPageViewController stiehlt jedes horizontale Panning, dies kann jedoch möglicherweise durch die Implementierung von Schaltflächen als Alternative zum Scrollen behoben werden.

Die UIControl hatte keine Gestenerkenner, aber ich überschreibe die beginTrackingWithTouch: und andere Methoden, um die Berührungen zu verfolgen.

Ich denke, die Antwort sollte sein: Wenn Sie zu viele Gesten schichten, machen Sie es falsch.

0

Sie benötigen einen Behälter auf das Rad hinzuzufügen, und dann kann man so etwas tun, wenn ich nicht etwas fehlt bin, muss dieser Code arbeiten.

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

Ich glaube, Sie würden drei verschiedene UIPanGesture Objekte definiert haben und befestigt sie an die entsprechenden Ansichten.

Obwohl dies technisch korrekt ist, kann es zu Verwirrungen kommen, beispielsweise wenn Sie mehrere überlappende Ansichten haben (Sie haben hier drei) und müssen eine Berührung an eine Ansicht senden, die nicht oben in der Ansicht angezeigt wird stapeln was würde passieren? Die Geste könnte am Ende verwirrend sein.

Stattdessen ist es möglich, einen einzelnen Gestenerkenner an die Übersicht mehrerer Zielansichten anzuhängen und die Geste an die richtige Ansicht zu delegieren, basierend auf den Koordinaten des Berührpunkts des Benutzers. Dazu müssen Sie die Berührungskoordinaten normalisieren, die von einer der Unteransichten der Superview stammen, in der UIPanGesture definiert ist. Auf diese Weise können Sie wissen, wo die Pfanne auf dem Rad oder anderswo passiert ist.

PS: Dies gesagt, ich fühle stark, das ist ein Design-Gotcha und es wird dir weh tun.Ich habe solche Dinge getan, aber irgendwann stolperst du über einen Eckfall, wo die Benutzerinteraktion schrecklich wäre. Wenn dies die Hauptansicht Ihrer App ist, schlage ich vor, dass Sie das Design überdenken.

0

Mit welchen Techniken kann ich diese Gestenerkenner eindeutig trennen?

Sie sollten die UIGestureRecognizerDelegate Methode suchen in:

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

fordert die Delegierten, wenn zwei Geste Erkenner erlaubt sein sollte, Gesten gleichzeitig zu erkennen.

Diese Methode wird aufgerufen, wenn die Erkennung einer Geste durch entweder "GestenRecognizer" oder "AndererGesichtRecognikator" den anderen Gestenerkenner daran hindert, seine Geste zu erkennen. Beachten Sie, dass die Rückgabe von YES die gleichzeitige Erkennung garantiert; die Rückgabe von NEIN andererseits garantiert nicht die gleichzeitige Erkennung, da der Delegat des anderen Gestenerkenners JA zurückgeben kann.

Ich glaube, das wird Ihr Problem der Gesten lösen, die von anderen Gesten "überholt" werden.

Verwandte Themen