0

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

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

    }

}
4

2 回答 2

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

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

于 2017-02-03T18:01:04.160 回答
0

有两种基本方法:

  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约束的。


关于这个拖拽逻辑的几点观察:

  • 您可能想要使用预测触摸(如上)来减少拖动的延迟。

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

于 2017-02-03T18:07:03.850 回答