UIView转换后拖动行为错误

时间:2016-07-09 21:30:12

标签: ios swift transform draggable

我有一个自定义DraggableView,它是UIImageView的子类。我用相机拍照,将结果UIImage添加到DraggableView然后我可以按照预期在屏幕上拖动它。

现在,如果原始照片是横向拍摄的,我会使用以下方式旋转:

if (image?.size.width > image?.size.height)
{
   self.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2))
}

当我应用此转换时,拖动行为仍然有效,但方向都是错误的 - 如果我向左拖动,图像会向上移动,而不是向左移动。如果我向上拖动,图像会向右移动,而不是向上移动。

我该如何解决这个问题?我想这与UIPanGestureRecognizer绑定到非转换视图有什么关系?

编辑:当前UIPanGestureRecognizer处理程序:

func onPhotoDrag(recognizer: UIPanGestureRecognizer?)
{
    let translation = recognizer!.translationInView(recognizer?.view)
    recognizer!.view!.center = CGPointMake(recognizer!.view!.center.x 
            + translation.x, recognizer!.view!.center.y + translation.y);
    recognizer?.setTranslation(CGPointZero, inView: recognizer?.view)

    if (recognizer!.state == UIGestureRecognizerState.Ended)
    {
        let velocity = recognizer!.velocityInView(recognizer?.view)
        let magnitude = sqrt((velocity.x * velocity.x) 
                + (velocity.y * velocity.y))
        let slideMult = magnitude / 300;
        let slideFactor = 0.1 * slideMult;
        let finalPoint = CGPointMake(recognizer!.view!.center.x 
                + (velocity.x * slideFactor), 
                recognizer!.view!.center.y + (velocity.y * slideFactor));

        // Animate the drag, and allow the drag delegate to do its work
        DraggableView.animateWithDuration(Double(slideFactor), 
                delay: 0, options: UIViewAnimationOptions.CurveEaseOut,
                animations: { recognizer?.view?.center = finalPoint },
                completion: {(_) -> Void in self.dragDelegate?.onDragEnd(self)})
    } // if: gesture ended
}

1 个答案:

答案 0 :(得分:2)

更新

感谢您发布您的代码。我将您的代码粘贴到我的DraggableImageView并重现您的问题。虽然我的版本正在处理旋转的视图(没有动画),但是你的版本正在横向移动。

不同之处在于我的代码要求可拖动视图的translationInView中的superview。您需要在可拖动视图的translationInView中询问velocityInViewsuperview

更改此行:

let translation = recognizer!.translationInView(recognizer?.view)

为:

let translation = recognizer!.translationInView(recognizer?.view?.superview)

并改变这一点:

let velocity = recognizer!.velocityInView(recognizer?.view)

为:

let velocity = recognizer!.velocityInView(recognizer?.view?.superview)

所有人都会很高兴。

上一个答案:

试试这个版本:

class DraggableImageView: UIImageView {

    override var image: UIImage? {
        didSet {
            if (image?.size.width > image?.size.height)
            {
                self.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2))
            }
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)

        self.setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        self.setup()
    }

    func setup() {
        self.userInteractionEnabled = true

        let panGestureRecognizer = UIPanGestureRecognizer()
        panGestureRecognizer.addTarget(self, action: #selector(draggedView(_:)))
        self.addGestureRecognizer(panGestureRecognizer)
    }

    func moveByDeltaX(deltaX: CGFloat, deltaY: CGFloat) {
        self.center.x += deltaX
        self.center.y += deltaY
    }

    func draggedView(sender:UIPanGestureRecognizer) {
        if let dragView = sender.view as? DraggableImageView, superview = dragView.superview {
            superview.bringSubviewToFront(dragView)
            let translation = sender.translationInView(superview)
            sender.setTranslation(CGPointZero, inView: superview)
            dragView.moveByDeltaX(translation.x, deltaY: translation.y)
        }
    }
}

使用示例:

override func viewDidLoad() {
    super.viewDidLoad()

    let dragView = DraggableImageView(frame: CGRect(x: 50, y: 50, width: 96, height: 128))

    dragView.image = UIImage(named: "landscapeImage.png")

    self.view.addSubview(dragView)
}