問題是您的翻譯是累積性的,因爲translationInView
是從連續手勢開始的,但是您要將翻譯添加到當前幀,而不是原始幀。這可以通過檢查手勢狀態來解決,並且如果您處於手勢的起始位置,則保存原始幀,然後在手勢繼續時將其用作將來翻譯的基礎。
-(void) panningMyView:(UIPanGestureRecognizer*) panGesture
{
static CGRect originalFrame; // or you could make this a non-static class ivar
if (panGesture.state == UIGestureRecognizerStateBegan)
{
originalFrame = self.myPanningView.frame;
}
else if (panGesture.state == UIGestureRecognizerStateChanged)
{
CGPoint translation = [panGesture translationInView:self.view];
if (translation.x > 0) {
CGRect newFrame = originalFrame;
newFrame.size.width += translation.x;
newFrame.size.height += translation.y;
self.myPanningView.frame = newFrame;
}
}
}
注意,我擺脫oldPoint
因爲你似乎沒有使用它。我也將newPoint
更名爲translation
,因爲它不是屏幕上的一個點,而是衡量您的手指在屏幕上移動(或翻譯)的程度。我也將oldRect
更名爲,因爲我認爲它更準確地捕捉了它是什麼。本質上,我試圖保留你的例程的邏輯,但只是澄清你的邏輯和變量名稱。我原以爲你可能需要一個額外的else if
原因,檢查結束或取消的手勢,使用動畫來完成或逆轉手勢,但我沒有解決這個問題,因爲你沒有在你的原始問題中引用它。
無論如何,我希望你能明白我們在這裏做什麼。我們正在保存原始幀並將其應用到該幀,而不是將其應用到當前幀。
更新:
在跟進的問題,你問你怎麼可能澄清動畫。你可能會這樣做:
-(void) panningMyView:(UIPanGestureRecognizer*) panGesture
{
static CGRect originalFrame; // or you could make this a non-static class ivar
CGPoint translation = [panGesture translationInView:self.view];
if (panGesture.state == UIGestureRecognizerStateBegan)
{
originalFrame = self.myPanningView.frame;
}
else if (panGesture.state == UIGestureRecognizerStateChanged)
{
if (translation.x > 0) {
CGRect newFrame = originalFrame;
newFrame.size.width += translation.x;
newFrame.size.height += translation.y;
self.myPanningView.frame = newFrame;
}
}
else if (panGesture.state == UIGestureRecognizerStateEnded ||
panGesture.state == UIGestureRecognizerStateCancelled ||
panGesture.state == UIGestureRecognizerStateFailed)
{
CGRect finalFrame = originalFrame;
// if we've gone more than half way, move it all the way,
// otherwise return it to the original frame
if (translation.x > (self.view.frame.size.width/2.0))
{
finalFrame.size.width += self.view.frame.size.width;
finalFrame.size.height += self.view.frame.size.height;
}
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.myPanningView.frame = finalFrame;
}
completion:nil];
}
}
來源
2012-12-25 17:54:29
Rob
很好的解釋,我搞砸了術語。但是,你讓他們很清楚。 – andyPaul
一切都在stateChanged中處理,因此在結束狀態中,可以顯示何種動畫,因爲最後一個框架維度在stateChanged中設置。 – andyPaul
@andyPaul我已經更新了我的答案,並添加了手勢動畫結尾的另一個示例。我所建議的是一些邏輯,它說:「嘿,如果我超過一半,將finalFrame設置爲最終幀大小,然後生成動畫。如果不超過一半,然後動畫返回這回到原來的大小「。顯然,我不知道什麼是合適的'finalFrame.size'值,所以我做了一個猜測,但是你必須改變它(以及'if'語句,'轉換'符合多少'超過一半「),但你明白了。 – Rob