【问题标题】:touchesBegan, touchesEnded, touchesMoved for moving UIViewtouchesBegan, touchesEnded, touchesMoved 用于移动 UIView
【发布时间】:2013-01-29 04:43:48
【问题描述】:

我需要拖动我的 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;
        }

    }


}

【问题讨论】:

  • 查看这个答案这个 SO 答案stackoverflow.com/a/4983124/1341626
  • 实际发生了什么?
  • 问题与移动物体有关。当我点击对象时,它必须记住坐标,然后当我们在方法 -touchesMoved 中重新计算它的框架时,它应该移动但它没有。它只向一个方向移动

标签: ios objective-c xcode uiview touchesbegan


【解决方案1】:

我建议使用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 不起作用的情况下使用这些。

【讨论】:

  • 没关系,谢谢,但是手势识别器没有在 touchesBegan 中调用的 touchDown 方法,只有 StateBegan。但是当我们移动对象而不是当我们点击它时,StateBegan 以一种方式工作
  • 是的,您可以使用 UIGestureRecognizerStateBegan、UIGestureRecognizerStateChanged、UIGestureRecognizerStateEnded、UIGestueRecognizerStateCancelled、UIGestureRecognizerStateFailed。 UIGestureRecognizerStateBegan 将为您提供初始触摸(在平移上)。如果您想要不同的点击操作,请添加 UITapGesture
  • 嗨 self.panCoord 是什么变量?
  • 嗨,我想知道如何在视图中移动标签或其他东西? “self.panCoord”是 CGPoint 吗?
【解决方案2】:

这是移动 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;
        }
    }
}

【讨论】:

    【解决方案3】:

    你的代码有些奇怪。

    您要求self 中的位置,一些 UIView 大概包含您要检查的UILabel。这就引出了一个问题,即为什么不将 touchesXXX 添加到您的某些 UILabel 子类中。

    当您使用根据其 superview.bounds 定义的 label.frame(您询问触摸位置的父 UIView)时,这会取消,但这并不是最直接的方式关注正在发生的事情。

    【讨论】:

    • 是的,你说得对,我已将 self 更改为 touch.view 并删除 if 块以检查矩形中的点。谢谢
    【解决方案4】:

    使用此代码,我可以将我的 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
    

    希望它有所帮助,尽管它是另一种方法而不是所提到的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-21
      • 2016-01-20
      • 2023-03-09
      • 1970-01-01
      • 2011-11-10
      相关资源
      最近更新 更多