5

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

-(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)];
}
}

しかし、私はアプリからいくつかの奇妙な応答を受け取っています。イメージビューが移動できる距離、つまり画面から消えないようにするための制限はありませんが、小さな動きでも、イメージビューがワイルドになって消えてしまいます。

すべての助けを事前にたくさんありがとう

4

2 に答える 2

9

この現代の世界では、実装touchesBeganなどはやり過ぎです。あなたは自分自身を混乱させているだけであり、あなたのコードはすぐに理解または維持することが不可能になります。UIPanGestureRecognizerを使用します。それが目的です。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];
    }
}
于 2012-02-03T03:59:20.793 に答える
2

コードには2つの問題があります。まず、この行は間違っています:

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

これである必要があります:

CGPoint lastTouch = [touch previousLocationInView:maskPreview];

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

CGPoint lastTouch = [touch locationInView:maskPreview];

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

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

また、のドキュメントにtouchesBegan:withEvent:は次のように書かれています。

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

したがって、オーバーライドしていることを確認してtouchesEnded:withEvent:くださいtouchesCancelled:withEvent:

とにかく、これはかなり簡単に行うことができます。1つの方法は、との両方を使用し、の代わりに更新することによってtouchesBegan:withEvent:、空にしてすべての作業を実行することです。インスタンス変数も必要ありません。touchesMoved:withEvent:previousLocationInView:locationInView:maskPreview.centermaskPreview.frameoriginalOrigin

-(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です。読者の練習問題として残しておきます。

于 2012-02-03T04:06:45.563 に答える