touchesBegan, 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;
        }

    }


}

person Matrosov Alexander    schedule 13.02.2013    source источник
comment
проверьте этот ответ, этот ответ SO stackoverflow.com/a/4983124/1341626   -  person luksfarris    schedule 13.02.2013
comment
Что происходит на самом деле?   -  person trojanfoe    schedule 13.02.2013
comment
проблема связана с движущимся объектом. когда я нажимаю на объект, он должен помнить координаты, а затем, когда мы пересчитываем его кадр в методе -touchesMoved, он должен двигаться, но этого не происходит. он движется только в одном направлении   -  person Matrosov Alexander    schedule 13.02.2013


Ответы (4)


В вашем коде что-то странное.

Вы запрашиваете местоположение в self, некоторый UIView, который предположительно содержит UILabel, который вы хотите проверить. Возникает вопрос, почему вы не добавляете touchesXXX в какой-нибудь из ваших подклассов UILabel.

Это отменяется, поскольку вы используете label.frame, который определяется с точки зрения его superview.bounds (ваш родительский UIView, в отношении которого вы запрашивали местоположение касания), но это не самый простой способ следовать тому, что продолжается.

person verec    schedule 13.02.2013
comment
да, вы правы, я изменил себя на touch.view и удалил блок if для проверки точки в прямоугольнике. Благодарность - person Matrosov Alexander; 13.02.2013

Я бы предложил использовать 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);
}

Это просто мое предпочтение. Для меня намного проще использовать распознаватель жестов, чем использовать touchesBegan, touchesEnded, touchesMoved. Я буду использовать их в тех случаях, когда UIPanGestureRecognizer не сработает.

person Jaybit    schedule 13.02.2013
comment
это нормально, спасибо, но у распознавателя жестов нет метода touchDown, который вызывает, например, в touchesBegan, только StateBegan. но StateBegan работает одним способом, когда мы перемещаем объект, а не когда нажимаем на него - person Matrosov Alexander; 13.02.2013
comment
Да, вы можете использовать UIGestureRecognizerStateBegan, UIGestureRecognizerStateChanged, UIGestureRecognizerStateEnded, UIGestueRecognizerStateCancelled, UIGestureRecognizerStateFailed. UIGestureRecognizerStateBegan даст вам первое касание (на панораме). Если вы хотите другое действие для тапа, добавьте UITapGesture - person Jaybit; 13.02.2013
comment
Привет, что за переменная self.panCoord? - person uplearnedu.com; 24.01.2014
comment
Привет, просто интересно, как бы я переместил метку или что-то в представлении с этим? Является ли self.panCoord CGPoint? - person uplearnedu.com; 24.01.2014

Это рабочий код для перемещения объектов UIView.

поплавок старыйX, старыйY; 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;
        }
    }
}
person Matrosov Alexander    schedule 13.02.2013

С помощью этого кода я мог перемещать свой объект 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

Надеюсь, это поможет, хотя это другой способ сделать это, чем тот, о котором идет речь.

person Nappa    schedule 29.12.2016