web-dev-qa-db-ja.com

touchesBegin、touchesEnded、touchesMovedはUIViewの移動用

UIViewオブジェクトをドラッグする必要があります。このコードを使用しますが、機能しません

float oldX, oldY;
BOOL dragging;

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

    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:self];

    if ([[touch.view class] isSubclassOfClass:[UILabel class]]) {
        UILabel *label = (UILabel *)touch.view;
        if (CGRectContainsPoint(label.frame, touchLocation)) {
            dragging = YES;
            oldX = touchLocation.x;
            oldY = touchLocation.y;
        }
    }


}

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

    dragging = NO;
}

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

    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:self];

    if ([[touch.view class] isSubclassOfClass:[UILabel class]]) {
        UILabel *label = (UILabel *)touch.view;

        if (dragging) {
            CGRect frame = label.frame;
            frame.Origin.x = label.frame.Origin.x + touchLocation.x - oldX;
            frame.Origin.y =  label.frame.Origin.y + touchLocation.y - oldY;
            label.frame = frame;
        }

    }


}
20

コードには少し奇妙なことがあります。

確認したいselfを含むと思われるUIViewであるUILabelの場所を要求します。これは、touchesXXXをUILabelのサブクラスに追加しない理由について疑問を投げかけます。

これは、superview.bounds(親のUIViewに関してタッチ位置を尋ねた)で定義されたlabel.frameを使用しているためキャンセルされますが、これは何を追跡する最も簡単な方法にはなりません起こっている。

0
verec

UIPanGestureRecognizerを使用することをお勧めします。

-(void)dragging:(UIPanGestureRecognizer *)gesture
{
    // Check if this is the first touch
    if(gesture.state == UIGestureRecognizerStateBegan)
    {
        // Store the initial touch so when we change positions we do not snap
        self.panCoord = [gesture locationInView:gesture.view];
        [self.view bringSubviewToFront:gesture.view];

    }

    CGPoint newCoord = [gesture locationInView:gesture.view];

    // Create the frame offsets to use our finger position in the view.
    float dX = newCoord.x-self.panCoord.x;
    float dY = newCoord.y-self.panCoord.y;

    gesture.view.frame = CGRectMake(gesture.view.frame.Origin.x+dX,
                                    gesture.view.frame.Origin.y+dY,
                                    gesture.view.frame.size.width, 
                                    gesture.view.frame.size.height);
}

これは私の好みです。私にとっては、touchesBegantouchesEndedtouchesMovedを使用するジェスチャレコグナイザーを使用する方がはるかに簡単です。 UIPanGestureRecognizerが機能しない場合にこれらを使用します。

15
Jaybit

これは、UIViewオブジェクトを移動するための作業コードです

float oldX、oldY; BOOLドラッグ;

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:touch.view];
    if ([[touch.view class] isSubclassOfClass:[UILabel class]]) {
        dragging = YES;
        oldX = touchLocation.x;
        oldY = touchLocation.y;
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    dragging = NO;
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:touch.view];    
    if ([[touch.view class] isSubclassOfClass:[UILabel class]]) {
        UILabel *label = (UILabel *)touch.view;
        if (dragging) {
            CGRect frame = label.frame;
            frame.Origin.x = label.frame.Origin.x + touchLocation.x - oldX;
            frame.Origin.y = label.frame.Origin.y + touchLocation.y - oldY;
            label.frame = frame;
        }
    }
}
14

このコードを使用すると、UIViewオブジェクトをどこにでも移動できます。私のViewController.Swiftは次のようになります。

// code from below

import UIKit

class ViewController: UIViewController {

    var location = CGPoint(x: 0, y: 0)

    @IBOutlet weak var Person: UIImageView!

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        var touch : UITouch! =  touches.first! as UITouch

        location = touch.location(in: self.view)

        Person.center = location

    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

        var touch : UITouch! =  touches.first! as UITouch

        location = touch.location(in: self.view)

        Person.center = location
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        Person.center = CGPoint(x: 160, y: 330)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

//ends

それが役立つことを願っていますが、それは問題に言及されているものとは別の方法です。

0
Nappa