2016-05-27 22 views
1

は、下の画像のように、内部の大きなカスタムUIImageViewを持つUITableViewCellを持っていると仮定します。 UITableViewCellにUILongPressGestureRecOgnizerを追加しました。私はこの動きがUITableViewCellの境界にあることを望みます。私は今何をやったか enter image description hereドラッグ可能なUIViewをSuperViewの境界に制限する

は:

UIView *view = sender.view; 
CGPoint point = [sender locationInView:view.superview]; 
if (sender.state == UIGestureRecognizerStateChanged) 
{ 
    CGPoint oldCenter = view.center; 
    CGPoint newCenter = oldCenter; 
    CGFloat deltaX = point.x - _priorPoint.x; 
    CGFloat deltaY = point.y - _priorPoint.y; 
    newCenter.x += deltaX; 
    newCenter.y += deltaY; 
    CGRect oldFrame = view.frame; 
    CGRect newFrame = CGRectMake(oldFrame.origin.x + deltaX, oldFrame.origin.y+deltaY, view.width, view.height); 

    if (CGRectContainsRect(newFrame, self.bounds)) { 
     self.customImageView.center = newCenter; 
    } 
    else 
    { 
     CGFloat newX = newFrame.origin.x; 
     CGFloat newY = newFrame.origin.y; 
     if (newX<view.x) { 
      newX = oldFrame.origin.x; 
     } 
     else if ((newFrame.origin.x + newFrame.size.width)>view.right) 
     { 
      newX = oldFrame.origin.x; 
     } 

     if (newY<view.y) { 
      newY = oldFrame.origin.y; 
     } 
     else if ((newY + newFrame.size.height)>view.bottom) 
     { 
      newY = view.y; 
     } 
     NSLog(@"newX:%f, newY:%f", newX, newY); 
     newFrame = CGRectMake(newX, newY, view.width, view.height); 
     self.customImageView.frame = newFrame; 
    } 
_priorPoint = point; 

問題は、私は斜めに私の指を移動すると、画像の動きが少しぎくしゃくです。例えば、Xが範囲外の場合、Yが有効な場合は、Yポイントを更新する必要があります。 ここに何が間違っていますか?何か考えていますか?

+1

なぜ画像の内容でスクロールビューを使用しないのですか?ロングプレスレコグナイザーでスクロールを有効または無効にすることができます。同時にジェスチャー認識も許可する必要があります。 – fabe

答えて

2

私はこれのために行うことは従うことが少し難しいですが、ここに行く...私は動いているビュー内のタッチインタラクションを行います。 In touchesBegan

drawingFrame = self.frame; 
initialViewOrigin = self.frame.origin; 
startingTouch = [[touches anyObject] locationInView:[self superview]]; 

これらはすべてクラス変数です。すべての楽しさのものがscrollLimit機能で起こる

lastTouchPoint = [[touches anyObject] locationInView:[self superview]]; 
float newLocationX = initialViewOrigin.x + (p.x - startingTouch.x); 
float newLocationY = initialViewOrigin.y + (p.y - startingTouch.y); 

//Do some location checks for sending it too far off the screen or whatnot 

drawingFrame.origin = [self scrollLimit:newLocationX y:newLocationY]; 

CGRect frame = self.frame; 
frame.origin.x = drawingFrame.origin.x; 
frame.origin.y = drawingFrame.origin.y; 
self.frame = frame; 

touchesMovedに続いて

-(CGPoint)scrollLimit:(float)x1 y:(float)y1 
{ 
    //My app always requires landscape, so make sure the parent's sizes are taken accordingly 
    int parentHeight = MIN(self.superview.frame.size.width,self.superview.frame.size.height); 
    int parentWidth = MAX(self.superview.frame.size.width,self.superview.frame.size.height); 

    if(self.frame.size.width < parentWidth) 
    { 
     if(x1 < 1) 
     { 
      x1 = 1; 
     } 
     else if(x1 >= parentWidth - self.frame.size.width) 
     { 
      x1 = parentWidth - self.frame.size.width; 
     } 
    } 
    else{ 
     x1 = initialViewOrigin.x; 
    } 


    if(self.frame.size.height < parentHeight) 
    { 
     if(y1 < 1) 
     { 
      y1 = 1; 
     } 
     else if(y1 > parentHeight - self.frame.size.height) 
     { 
      y1 = parentHeight - self.frame.size.height; 
     } 
    } 
    else{ 
     y1 = initialViewOrigin.y; 
    } 

    return CGPointMake(x1,y1); 

} 

このすべてがビューでは、私の場合には(単にスーパーを設定範囲内に留まることを確認しますまた、ドラッグ・エクスペリエンスをスムーズかつリアルにします。私が見たいくつかの他の方法は、あなたの指があなたがスクロールしているアイテムから降りて、決して同期を取り戻さないことがあります。私のコードはあなたのためにはうまくいきませんが、正しい方向にあなたを得るはずです。

私の方法では、境界スーパービューボックスを維持したまま、ビュー「投げ」のシミュレーション慣性も持っています。それはあなたの質問の外にあり、完璧になるまでには非常に時間がかかったので、私はそれを読者に練習として残しておきます...

+0

これは、 'UIImageView'のサイズがsuperViewよりも小さい場合に有効です。私の場合、imageViewはsuperViewより大きい。 –

+1

ドラッグする範囲を任意の次元に設定できます。私はスーパービューを使用しています。なぜなら、それらは私が必要としている範囲だからです。 scrollLimit関数で必要なサイズと位置にCGRectを作成し、その範囲にモーションを制限してください。スーパービューに限定される必要はありません... – Putz1103

関連する問題