【问题标题】:Drag behaviour wrong after UIView transformationUIView 转换后拖动行为错误
【发布时间】:2016-11-12 04:41:36
【问题描述】:

我有一个自定义的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
}

【问题讨论】:

  • 你能发布你的可拖动视图的 panGestureHandler 代码吗?
  • 而不是 DraggableView 继承 UIImageView,使其成为 UIView 的子类,然后将旋转后的 UIImageView 添加为子类。
  • 已编辑以添加处理程序。我在DraggableViewinit 中进行旋转,但尝试答案中的方法没有任何区别。

标签: ios swift transform draggable


【解决方案1】:

更新:

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

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

改变这一行:

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)
}

【讨论】:

  • 我试过这个,我看到它想做什么,但它没有用。根据@vacawama 的要求,我添加了当前的 pan 处理程序。
  • 这如描述的那样工作,我明白为什么。谢谢!
  • 我还应该说,这会阻止我从顶部的照片后面拖动(就像我以前可以做的那样),因为用于拖动的框架现在要大得多,但我可以解决这个问题稍后。
  • 嗯。我不明白你最近的评论。这种变化仅仅是坐标到正确视图坐标的数学变换。这对您可以选择的内容有何影响?
  • DraggableView 框架刚刚超出了显示的边界,然后我调整了图像,这以前是绑定到拖动行为的。我认为我需要更聪明地调整框架的大小。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
相关资源
最近更新 更多