2012-02-03 9 views
5

私は自分のimageView(以下のコードではmaskPreview)に動きのある機能を作成しようとしているので、ユーザーはmaskPreviewに含まれている画像を画面上で動かすことができます。タッチの開始とタッチの移動に関するコードは次のとおりです。TouchでUIImageViewを移動する方法

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
if ([touches count]==1) { 
    UITouch *touch= [touches anyObject]; 
    originalOrigin = [touch locationInView:maskPreview]; 
} 
} 
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
if ([touches count]==1) { 
    UITouch *touch = [touches anyObject]; 
    CGPoint lastTouch = [touch previousLocationInView:self.view]; 
    CGFloat movedDistanceX = originalOrigin.x-lastTouch.x; 
    CGFloat movedDistanceY = originalOrigin.y-lastTouch.y; 
    [maskPreview setFrame:CGRectMake(maskPreview.frame.origin.x+movedDistanceX, maskPreview.frame.origin.y + movedDistanceY, maskPreview.frame.size.width, maskPreview.frame.size.height)]; 
} 
} 

しかし、私はアプリからいくつかの奇妙な応答を得ています。画像ビューの移動距離、つまり画面外への移動を制限することはしていませんが、小さな動きであっても画像ビューが荒くなり消えてしまいます。たくさんようにtouchesBeganとを実装するすべてのヘルプ

答えて

9

を事前に

おかげで、この現代の世界で道過剰です。あなたはちょうどあなた自身のことを混乱させているだけで、あなたのコードはすぐに理解したり維持することが不可能になります。 UIPanGestureRecognizerを使用します。それが何のためだ。 UIPanGestureRecognizerでビューをドラッグ可能にするのは簡単です。あなたのコードには二つの問題があります

- (void) dragging: (UIPanGestureRecognizer*) p { 
    UIView* vv = p.view; 
    if (p.state == UIGestureRecognizerStateBegan || 
     p.state == UIGestureRecognizerStateChanged) { 
     CGPoint delta = [p translationInView: vv.superview]; 
     CGPoint c = vv.center; 
     c.x += delta.x; c.y += delta.y; 
     vv.center = c; 
     [p setTranslation: CGPointZero inView: vv.superview]; 
    } 
} 
+0

驚くばかりのマット、あなたは絶対的な天才です!あなたの答えを評価したでしょうか?私は十分な評判を持っていません!私の人生はとても楽になりました!! – Septronic

+0

ちょうどFYI、そのコードは私の本のまっすぐ来た:http://shop.oreilly.com/product/0636920023562.do - それはどこから来た多くの... – matt

+0

素晴らしい、私はそれを見て:)感謝 – Septronic

2

:ここではドラッグ可能なビューを作るUIPanGestureRecognizerためのアクションハンドラです。まず、この行が間違っている:それは、このする必要があります

CGPoint lastTouch = [touch previousLocationInView:self.view]; 

:本当に

CGPoint lastTouch = [touch previousLocationInView:maskPreview]; 

、あなたもpreviousLocationInView:を使用すべきではありません。あなたはこのようlocationInView:を使用する必要があります。

CGPoint lastTouch = [touch locationInView:maskPreview]; 

第二に、あなたはmovedDistanceXmovedDistanceY間違ったの兆候を得ています。これにそれらを変更します。

CGFloat movedDistanceX = lastTouch.x - originalOrigin.x; 
CGFloat movedDistanceY = lastTouch.y - originalOrigin.y; 

また、touchesBegan:withEvent:のドキュメントがこれを言う:

あなたはsuper(一般的な使用パターン)を呼び出さずにこのメソッドをオーバーライドした場合、あなたはまたのために他のメソッドをオーバーライドする必要がありますスタブ(empy)実装の場合にのみ、タッチイベントを処理します。

touchesEnded:withEvent:touchesCancelled:withEvent:も上書きしてください。

いずれにしても、これをもっと簡単に行うことができます。 1つの方法はtouchesBegan:withEvent:を空にしてtouchesMoved:withEvent:のすべての作業をpreviousLocationInView:locationInView:の両方で行い、maskPreview.frameの代わりにmaskPreview.centerを更新することです。

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

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    if ([touches count]==1) { 
     UITouch *touch = [touches anyObject]; 
     CGPoint p0 = [touch previousLocationInView:maskPreview]; 
     CGPoint p1 = [touch locationInView:maskPreview]; 
     CGPoint center = maskPreview.center; 
     center.x += p1.x - p0.x; 
     center.y += p1.y - p0.y; 
     maskPreview.center = center; 
    } 
} 

これを実行する別の方法は、UIPanGestureRecognizerを使用することです:あなたもoriginalOriginインスタンス変数を必要としません。私はそれを読者のための練習として残す。

+0

こんにちはロブ、答えてくれてありがとう、私のコードで間違いを実現!私はUIPanGestureRecognizerのためのMattのチュートリアルを使いました。しかし、すべてのタッチイベントを乗り越えることについての大きな援助は大きな助けとなりました。わかりませんでした。 – Septronic

関連する問題