2012-12-25 131 views
2

爲了最小化和最大化UIView我正在使用UIPangestureRecognizer。代碼如下:UIPanGestureRecognizer最大化和最小化UIView

-(void) pannningMyView:(UIPanGestureRecognizer*) panGesture{ 
    CGPoint newPoint=[panGesture translationInView:self.view]; 
    CGPoint oldPoint=self.myPanningView.frame.origin; 
    CGFloat dx=newPoint.x; 
    CGFloat dy=newPoint.y; 
    if(dx>0){ 
     CGRect oldRect=self.myPanningView.frame; 
     oldRect.size.width+=dx; 
     oldRect.size.height+=dy; 
     self.myPanningView.frame=oldRect; 
    } 
} 

但是,過渡非常快,這樣我移動了幾個像素,它覆蓋了整個屏幕。我無法弄清楚我的代碼需要什麼修正。

回答

1

問題是您的翻譯是累積性的,因爲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]; 
    } 
} 
+0

很好的解釋,我搞砸了術語。但是,你讓他們很清楚。 – andyPaul

+0

一切都在stateChanged中處理,因此在結束狀態中,可以顯示何種動畫,因爲最後一個框架維度在stateChanged中設置。 – andyPaul

+0

@andyPaul我已經更新了我的答案,並添加了手勢動畫結尾的另一個示例。我所建議的是一些邏輯,它說:「嘿,如果我超過一半,將finalFrame設置爲最終幀大小,然後生成動畫。如果不超過一半,然後動畫返回這回到原來的大小「。顯然,我不知道什麼是合適的'finalFrame.size'值,所以我做了一個猜測,但是你必須改變它(以及'if'語句,'轉換'符合多少'超過一半「),但你明白了。 – Rob