UIView 转换后拖动行为错误
Posted
技术标签:
【中文标题】UIView 转换后拖动行为错误【英文标题】:Drag behaviour wrong after UIView transformation 【发布时间】: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 添加为子类。 已编辑以添加处理程序。我在DraggableView
的init
中进行旋转,但尝试答案中的方法没有任何区别。
【参考方案1】:
更新:
感谢您发布代码。我将您的代码粘贴到我的DraggableImageView
并重现了您的问题。虽然我的版本正在处理旋转视图(没有动画),但你的版本是横向的。
不同之处在于我的代码在可拖动视图的superview
中要求translationInView
。您需要在可拖动视图的superview
中询问translationInView
和velocityInView
。
改变这一行:
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
框架刚刚超出了显示的边界,然后我调整了图像,这以前是绑定到拖动行为的。我认为我需要更聪明地调整框架的大小。以上是关于UIView 转换后拖动行为错误的主要内容,如果未能解决你的问题,请参考以下文章
UITableViewCell 中自定义 UIView 的 drawRect 行为错误
在 tableview 滚动和再次拖动 tableview 上动画 UIView 位置