Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何拖动图像_Ios_Swift_Iboutletcollection - Fatal编程技术网

Ios 如何拖动图像

Ios 如何拖动图像,ios,swift,iboutletcollection,Ios,Swift,Iboutletcollection,我可以使用下面的代码移动单个ui视图,但如何使用IBOutletCollection和标记值分别移动多个ui视图 class TeamSelection: UIViewController { var location = CGPoint(x: 0, y: 0) @IBOutlet weak var ViewTest: UIView! // move a single image @IBOutlet var Player: [UIView]! // collectio

我可以使用下面的代码移动单个
ui视图
,但如何使用
IBOutletCollection
标记
值分别移动多个
ui视图

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

    }

}
类组选择:UIViewController{
变量位置=CGPoint(x:0,y:0)
@ibvar-ViewTest:UIView!//移动单个图像
@IBOutlet var Player:[UIView]!//用于仅使用一个插座启用不同图像的集合
覆盖功能触摸移动(touchs:Set,带有事件:UIEvent?){
让触摸:UITouch=touch.first!作为UITouch
位置=触摸位置(在:self.view中)
ViewTest.center=位置
}
}

我将创建一个支持拖动的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)
        }
    }

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

有两种基本方法:

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

  • 就我个人而言,我会将拖动逻辑放在子视图中:

    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)
        }
    }
    
    class CustomView:UIView{//或子类'UIImageView',根据需要
    私人var原始中心:CGPoint?
    私有变量dragStart:CGPoint?
    覆盖func TouchesBegind(Touchs:Set,带有事件:UIEvent?){
    原点=中心
    dragStart=touchs.first!。位置(在:superview中)
    }
    覆盖功能触摸移动(touchs:Set,带有事件:UIEvent?){
    guard let touch=touch.first else{return}
    变量位置=触摸位置(在:superview中)
    如果let predicted=event?.predictedtouchs(for:touch)?.last{
    位置=预测。位置(在:superview中)
    }
    中心=dragStart!+位置-原始中心!
    }
    覆盖函数touchesend(touchs:Set,带有事件:UIEvent?){
    guard let touch=touch.first else{return}
    让位置=触摸位置(在:superview中)
    中心=dragStart!+位置-原始中心!
    }
    }
    扩展点{
    静态函数+(左:CGPoint,右:CGPoint)->CGPoint{
    返回点(x:lhs.x+rhs.x,y:lhs.y+rhs.y)
    }
    静态函数-(左:CGPoint,右:CGPoint)->CGPoint{
    返回点(x:lhs.x-rhs.x,y:lhs.y-rhs.y)
    }
    }
    
    如果使用此方法,请记住为子视图设置“已启用用户交互”

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


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

    • 您可能希望使用如上所述的预测性触摸来减少拖拽的滞后性

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


    谢谢,我将如何使用@IBOutlet var Player:[UIView]!在函数内移动image@Chet-你有出口这一事实无关紧要。问题是如何实例化这些视图。例如,如果在IB中,请确保将这些播放器视图的基类指定为上面所示的自定义类。但是所有的
    @IBOutlet
    内容都没有更改,我忘了将子类分配给ImagueView确保在DragTableView(即如果它是imageView)和SuperView上isUserInteractionEnabled设置为true。