我可以使用下面的代码移动单个UIView
,但如何使用UIView
和IBOutletCollection
值单独移动多个tag
?
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
}
}
答案 0 :(得分:0)
我创建了一个支持拖动的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)
}
}
然后,您可以添加一个可拖动视图数组,然后在需要完成显示该视图控制器时询问位置。
答案 1 :(得分:0)
有两种基本方法:
您可以遍历您的子视图,找出触摸相交的哪一个并移动它。但是这种方法(也没有使用神秘的tag
数值来识别视图)通常不是首选方法。
就个人而言,我将拖拽逻辑放在子视图中:
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)
}
}
请务必设置&#34;启用用户互动&#34;对于子视图,如果您使用此方法。
顺便说一下,如果您要拖动这样的视图,请确保您没有对这些视图进行约束,否则当自动布局引擎接下来应用时,一切都会移回到原来的位置。如果使用自动布局,您通常会修改约束的constant
。
关于拖拽逻辑的几点意见:
您可能希望使用预测触摸(如上所述)来减少阻力的拖延。
我不想将center
移动到触摸的location(in:)
,而是希望通过拖动它来跟踪它,并相应地移动center
或应用相应的翻译。它是一个更好的用户体验,恕我直言,因为如果你抓住角落,它可以让你拖动角落,而不是让它跳到视图的中心到触摸屏幕的位置。