2012-04-05 9 views
7

Sobald ich touchesBegan erhalte, möchte ich removeFromSuperview die Ansicht, die berührt wurde und addSuperview zu einer neuen übergeordneten Ansicht, und dann weiterhin Berührungen erhalten. Ich finde jedoch, dass das manchmal nicht funktioniert. Insbesondere werden touchesMoved und touchesEnded nie aufgerufen.iOS: Eigentumsrechte an UIView übertragen, während Berührungen passieren?

Gibt es einen Trick, um dies richtig zu machen? Dies dient zum Implementieren eines Drag & Drop-Verhaltens, bei dem sich die Ansicht zunächst in einer Bildlaufansicht befindet.

Danke.

Antwort

0

Sie müssen Ihre Berührungen in der Superview verarbeiten, anstatt in der Ansicht, die Sie ausschalten möchten. Dadurch können Sie die Ansicht wechseln, ohne Ihre Berührungsereignisse zu verlieren. Wenn Sie dies jedoch tun, müssen Sie selbst testen, ob die Berührung in der bestimmten Unteransicht auftritt, die Sie ausschalten möchten. Dies kann viele Arten erfolgen, aber hier sind einige Methoden, die Sie zu erhalten begonnen:

Converting Rects/Point in einer anderen Ansicht:

[view convertRect:rect toView:subview]; 
[view convertPoint:point toView:subview]; 

Hier sind einige Methoden zu testen, ob der Punkt in der Ansicht befindet :

[subView hitTest:point withEvent:nil]; 
CGRectContainsPoint(subview.frame, point); //No point conversion needed 
[subView pointInside:point withEvent:nil]; 

Im Allgemeinen ist es besser, UIGestureRecognizers zu verwenden. Wenn Sie z. B. einen UIPanGestureRecognizer verwenden, erstellen Sie eine Methode, die der Gestenerkenner aufrufen kann und in der Sie Ihre Arbeit ausführen. Zum Beispiel:

- (void) viewPanned:(UIPanGestureRecognizer *)pan{ 
    if (pan.state == UIGestureRecognizerStateBegan){ 
     CGRect rect = subView.frame; 
     newView = [[UIView alloc] initWithFrame:rect]; 
     [subView removeFromSuperview]; 
     [self addSubview:newView]; 
    } else if (pan.state == UIGestureRecognizerStateChanged){ 
     CGPoint point = [pan locationInView:self]; 
     newView.center = point; 
    } else { 
     //Do cleanup or final view placement 
    } 
} 

Dann init Sie den Erkenner, weisen sie an das Ziel (in der Regel selbst) und fügen Sie:

[self addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewPanned:)]]; 

Jetzt selbst (der die Super wäre es Subviews Verwaltung) reagiert Bewegungen schwenken.

+0

Nicht sicher, warum das wäre. Kannst du Code schreiben? Übrigens, was hält Sie davon ab, einen UIGestureRecognizer zu benutzen? In fast allen Fällen, in denen ich die Verwendung von Touches in Erwägung gezogen habe, habe ich festgestellt, dass entweder ein vorhandener UIGestureRecognizer oder ein Unterklasse-UIGestureRecognizer besser funktioniert (und ich ihn wiederverwenden kann). –

+0

Wenn Sie den Bestand UIPanGestureRecognizer verwenden, sollte 'touchesBegan' nicht in Ihrem Code enthalten sein. Sie sollten einige Zielmethoden wie folgt einrichten: '- (void) viewPanned: (UIPanGestureRecognizer) pan '. Wenn Sie den Recognizer starten, setzen Sie sein Ziel: '[[UIPanGestureRecognizer alloc] initWithTarget: self action: @selector (viewPanned :)]'.Diese Methode wird wiederholt aufgerufen, und Sie können den Status überprüfen und die entsprechenden Aktionen ausführen: 'If (pan.state == UIGestureRecognizerStateBegan) {...} oder' If (pan.state == UIGestureRecognizerStateChanged {. ....} 'etc ... –

+0

Ich erweiterte meine Antwort, um dies zu widerspiegeln. –

7

Statt:

[transferView removeFromSuperView]; 
[newParentView addSubview:transferView]; 

Nur:

[newParentView addSubview:transferView]; 

Innerhalb der Dokumentation heißt es „Ansichten kann nur ein Super haben Sollte die Ansicht bereits ein Superview hat und dass. Ansicht ist nicht der Empfänger, diese Methode entfernt die vorherige Superansicht, bevor der Empfänger seine neue Superansicht erhält. "

Daher ist es nicht notwendig, removeFromSuperView zu verwenden, da es von addSubview behandelt wird. Ich habe bemerkt, dass removeFromSuperView alle aktuellen Berührungen beendet, ohne touchsEnded aufzurufen. Wenn Sie nur addSubview verwenden, werden Berührungen nicht unterbrochen.

+1

Dies sollte die akzeptierte Antwort sein, da es nicht notwendig ist, das Ziehen in der Superview zu verwalten, um das Ziel des OPs zu erreichen.Entfernen Sie einfach ** removeFromSuperView ** macht den Trick. Danke ** walapu **. – walkingbrad

+0

Große Antwort, das war sehr hilfreich! – Max