/ / Wie man eine ziehbare "Schublade" benutzerdefiniert implementiert UIView - ios, uiview, uiviewanimation, touch-event

Wie man eine ziehbare "Schublade" benutzerdefiniert implementiert UIView - ios, uiview, uiviewanimation, touch-event

Ich habe eine Gewohnheit UIView unten auf meinem View-Controller, der als fungierteine "Schublade" Kontrolle. Ungefähr 90 Pixel der Ansicht sind sichtbar. Wenn ein Benutzer auf die Ansicht tippt, wird diese nach oben animiert und zeigt weitere Optionen, Steuerelemente usw. an. Nach einem weiteren Antippen bewegt sich die Ansicht wieder in die ursprüngliche Position. Effektiv "die Schublade schließen".

Ich habe auch Code implementiert, so dass die Ansicht mit einer schleppenden Geste verfolgt:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

if(self.frame.origin.y >= 80) {
UITouch *theTouch = [touches anyObject];
CGPoint location = [theTouch locationInView:self];
CGPoint previousLocation = [theTouch previousLocationInView:self];
CGFloat target = location.y - previousLocation.y;
self.frame = CGRectOffset(self.frame, 0, target);
}
}

All dies funktioniert wie erwartet. Die Ansicht reagiert jedoch nicht korrekt auf eine schnelle "Flick" -Geste. In dem touchesEnded:withEvent: Methode Ich animiere die Ansicht von wo der Benutzerhob seinen Finger an sein Ziel. Dies funktioniert gut, wenn der Benutzer langsam schleppt und dann freigibt. Aber wenn sie schnell blättern, muss die Ansicht noch eine Dauer von 0,5 Sekunden verarbeiten, was für das Auge nicht glatt ist. Hier ist der gesamte Code der benutzerdefinierten Ansicht:

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

if(self.frame.origin.y >= 80) {
UITouch *theTouch = [touches anyObject];
CGPoint location = [theTouch locationInView:self];
CGPoint previousLocation = [theTouch previousLocationInView:self];
CGFloat target = location.y - previousLocation.y;
self.frame = CGRectOffset(self.frame, 0, target);
}
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if(self.frame.origin.y == kDefaultUpY) {
_comingFromUp = YES;
_comingFromDown = NO;
}
else if(self.frame.origin.y == kDefaultDownY) {
_comingFromUp = NO;
_comingFromDown = YES;
}
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

//responding to tap
if(self.frame.origin.y == kDefaultUpY) {
[UIView animateWithDuration:0.5f delay:0.0f usingSpringWithDamping:0.75f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
self.frame = CGRectMake(0, kDefaultDownY, self.frame.size.width, self.frame.size.height);
} completion:nil];

return;
}
else if(self.frame.origin.y == kDefaultDownY) {
[UIView animateWithDuration:0.5f delay:0.0f usingSpringWithDamping:0.75f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
self.frame = CGRectMake(0, kDefaultUpY, self.frame.size.width, self.frame.size.height);
} completion:nil];

return;
}

//responding to drag
if(_comingFromDown) {
if(self.frame.origin.y < kDefaultDownY) {
//dragging up -- go up
[UIView animateWithDuration:0.5f delay:0.0f usingSpringWithDamping:0.75f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
self.frame = CGRectMake(0, kDefaultUpY, self.frame.size.width, self.frame.size.height);
} completion:nil];
}
else if(self.frame.origin.y > kDefaultDownY) {
//dragging down -- stay down
[UIView animateWithDuration:0.5f delay:0.0f usingSpringWithDamping:0.75f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
self.frame = CGRectMake(0, kDefaultDownY, self.frame.size.width, self.frame.size.height);
} completion:nil];
}
}
else if(_comingFromUp) {
if(self.frame.origin.y < kDefaultUpY) {
//dragging up -- stay up
[UIView animateWithDuration:0.5f delay:0.0f usingSpringWithDamping:0.75f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
self.frame = CGRectMake(0, kDefaultUpY, self.frame.size.width, self.frame.size.height);
} completion:nil];
}
else if(self.frame.origin.y > kDefaultUpY) {
//dragging down -- go down
[UIView animateWithDuration:0.5f delay:0.0f usingSpringWithDamping:0.75f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
self.frame = CGRectMake(0, kDefaultDownY, self.frame.size.width, self.frame.size.height);
} completion:nil];
}
}
}

Wie kann ich auf die Gesten reagieren, die mit einer "Schubladen" -Ansicht verbunden sind? Gibt es eine Standardmethode, um diese Art von Funktionalität zu erreichen?

Antworten:

2 für die Antwort № 1

Verwenden Sie Gestenerkenner statt implementierenBerühre den Code selbst. Sie können sowohl eine Wischgestenerkennung als auch eine Schwenkgeste erkennen und die Schwenkgeste so einrichten, dass der Wischvorgang fehlschlägt, bevor der Schwenk ausgelöst wird. Machen Sie die Animation für die Wischgeste schneller. Etwas wie 0,1 oder 0,2 Sekunden ist wahrscheinlich richtig für eine Wischgeste.

Etwas, auf das man achten sollte: In iOS 7 löst eine Wischgeste am unteren Bildschirmrand aus, dass das Systemeinstellungsfach am unteren Bildschirmrand angezeigt wird. Unsere App Face Dancer hat eine Steuerschublade, und wir haben kürzlich festgestellt, dass es unter iOS 7 schwierig ist, unsere Steuerschublade nach oben zu schieben, ohne stattdessen die Schublade für Systemeinstellungen auszulösen. Wir haben einen "Daumen" -Region zum Ziehen, und wir fügen eine Tippgeste hinzu, die ihn vollständig in einem Schritt anzeigt / verdeckt.