如何拖动图像



我可以使用下面的代码移动单个UIView,但如何使用IBOutletCollectiontag值单独移动多个UIView

class TeamSelection: UIViewController {
var location = CGPoint(x: 0, y: 0)
@IBOutlet weak var ViewTest: UIView! // move a single image
@IBOutlet var Player: [UIView]! // collection to enable different images with only one outlet
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch: UITouch = touches.first! as UITouch
location = touch.location(in: self.view)
ViewTest.center = location
}
}

有两种基本方法:

  1. 您可以迭代子视图,找出触摸在哪个子视图中相交并移动它。但这种方法(也不是使用神秘的tag数值来识别视图)通常不是首选方法。

  2. 就我个人而言,我会把拖拽逻辑放在子视图中:

    class CustomView: UIView {      // or subclass `UIImageView`, as needed
    private var originalCenter: CGPoint?
    private var dragStart: CGPoint?
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    originalCenter = center
    dragStart = touches.first!.location(in: superview)
    }
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first else { return }
    var location = touch.location(in: superview)
    if let predicted = event?.predictedTouches(for: touch)?.last {
    location = predicted.location(in: superview)
    }
    center = dragStart! + location - originalCenter!
    }
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first else { return }
    let location = touch.location(in: superview)
    center = dragStart! + location - originalCenter!
    }
    }
    extension CGPoint {
    static func +(lhs: CGPoint, rhs: CGPoint) -> CGPoint {
    return CGPoint(x: lhs.x + rhs.x, y: lhs.y + rhs.y)
    }
    static func -(lhs: CGPoint, rhs: CGPoint) -> CGPoint {
    return CGPoint(x: lhs.x - rhs.x, y: lhs.y - rhs.y)
    }
    }
    

    如果使用这种方法,请记住为子视图设置"启用用户交互"。

  3. 顺便说一句,如果像这样拖动视图,请确保对这些视图没有约束,否则当自动布局引擎下次应用时,所有内容都会移回原始位置。如果使用自动布局,通常会修改约束的constant


关于拖动逻辑的几个观察结果:

  • 您可能需要使用预测触摸,如上面所述,以减少拖动的滞后性。

  • 与其将center移动到触摸的location(in:),我更愿意通过拖动它的程度来跟踪它,并相应地移动center或应用相应的平移。这是一个更好的用户体验,IMHO,因为如果你抓住角落,它可以让你拖动角落,而不是让它从视图的中心跳到屏幕上的触摸位置。

我会创建一个支持拖动的UIView子类。类似于:

class DraggableView: UIView {
func setDragGesture() {
let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(DraggableView.handlePanGesture(_:)))
addGestureRecognizer(panRecognizer)
}
func handlePanGesture(_ recognizer: UIPanGestureRecognizer) {
guard let parentView = self.superview else { return }
let translation = recognizer.translation(in: parentView)
recognizer.view?.center = CGPoint(x: recognizer.view!.center.x + translation.x, y: recognizer.view!.center.y + translation.y)
recognizer.setTranslation(CGPoint.zero, in: self)
}

func getLocation() -> CGPoint {
return UIView().convert(center, to: self.superview)
}
}

因此,您可以添加一组可拖动视图,然后在需要完成显示视图控制器时询问位置。

最新更新