如何实现多个PanGestures(可拖动视图)?

2024-01-10

我想要几个可以拖放的对象。

这是我移动一个对象的代码(在@vacawama 的帮助下):

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var panView: UIView!

@IBOutlet weak var panViewCenterX: NSLayoutConstraint!
@IBOutlet weak var panViewCenterY: NSLayoutConstraint!

let panRec = UIPanGestureRecognizer()

override func viewDidLoad() {
    super.viewDidLoad()

    panRec.addTarget(self, action: "draggedView:")
    panView.addGestureRecognizer(panRec)

// Do any additional setup after loading the view, typically from a nib.
}

func draggedView(sender:UIPanGestureRecognizer){

    self.view.bringSubviewToFront(sender.view!)
    var translation = sender.translationInView(self.view)

    panViewCenterY.constant += translation.y
    panViewCenterX.constant += translation.x

    sender.setTranslation(CGPointZero, inView: self.view)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}   

}

我想在我的项目中拥有更多对象:

 @IBOutlet weak var panView2: UIView!
 @IBOutlet weak var panView3: UIView!
 @IBOutlet weak var panView4: UIView!
 ...

那么,以我可以拥有多个的方式实现这一点的最简单方法是什么panView我可以独立移动哪一个(一次一个)?


如果您正在使用自动布局,您不应该仅仅通过改变视图的中心来移动视图。任何导致自动布局运行会将您的视图移回到原来的位置。

这是一个名为的新类的实现DraggableView自动布局提供可以拖动的视图。它在代码中为视图的宽度、高度、X 位置和 Y 位置创建约束。它使用自己的UIPanGestureRecognizer允许拖动视图。

DraggableView.swift可以放入任何需要可拖动视图的项目中。看一眼ViewController.swift下面看看它是多么容易使用。

DraggableView.swift

import UIKit

class DraggableView: UIView {
    let superView: UIView!
    let xPosConstraint:  NSLayoutConstraint!
    let yPosConstraint:  NSLayoutConstraint!
    var constraints: [NSLayoutConstraint] {
        get {
            return [xPosConstraint, yPosConstraint]
        }
    }

    init(width: CGFloat, height: CGFloat, x: CGFloat, y: CGFloat, color: UIColor, superView: UIView) {
        super.init()

        self.superView = superView

        self.backgroundColor = color

        self.setTranslatesAutoresizingMaskIntoConstraints(false)

        let panGestureRecognizer = UIPanGestureRecognizer()
        panGestureRecognizer.addTarget(self, action: "draggedView:")
        self.addGestureRecognizer(panGestureRecognizer)

        let widthConstraint = NSLayoutConstraint(item: self, attribute: .Width, relatedBy: .Equal,
            toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: width)
        self.addConstraint(widthConstraint)

        let heightConstraint = NSLayoutConstraint(item: self, attribute: .Height, relatedBy: .Equal,
            toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: height)
        self.addConstraint(heightConstraint)

        xPosConstraint = NSLayoutConstraint(item: self, attribute: .CenterX, relatedBy: .Equal,
            toItem: superView, attribute: .Leading, multiplier: 1.0, constant: x)

        yPosConstraint = NSLayoutConstraint(item: self, attribute: .CenterY, relatedBy: .Equal,
            toItem: superView, attribute: .Top, multiplier: 1.0, constant: y)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func moveByDeltaX(deltaX: CGFloat, deltaY: CGFloat) {
        xPosConstraint.constant += deltaX
        yPosConstraint.constant += deltaY
    }

    func draggedView(sender:UIPanGestureRecognizer){
        if let dragView = sender.view as? DraggableView {
            superView.bringSubviewToFront(dragView)
            var translation = sender.translationInView(superView)
            sender.setTranslation(CGPointZero, inView: superView)
            dragView.moveByDeltaX(translation.x, deltaY: translation.y)
        }
    }
}

ViewController.swift

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let dragView1 = DraggableView(width: 75, height: 75, x: 50, y: 50,
            color: UIColor.redColor(), superView: self.view)
        self.view.addSubview(dragView1)
        self.view.addConstraints(dragView1.constraints)

        let dragView2 = DraggableView(width: 100, height: 100, x: 150, y: 50,
            color: UIColor.blueColor(), superView: self.view)
        self.view.addSubview(dragView2)
        self.view.addConstraints(dragView2.constraints)

        let dragView3 = DraggableView(width: 125, height: 125, x: 100, y: 175,
            color: UIColor.greenColor(), superView: self.view)
        self.view.addSubview(dragView3)
        self.view.addConstraints(dragView3.constraints)
    }
}

UPDATE:

这是一个版本DraggableView.swift支持图像作为子视图。

import UIKit

class DraggableView: UIView {
    let superView: UIView!
    let xPosConstraint:  NSLayoutConstraint!
    let yPosConstraint:  NSLayoutConstraint!
    var constraints: [NSLayoutConstraint] {
        get {
            return [xPosConstraint, yPosConstraint]
        }
    }

    init(width: CGFloat, height: CGFloat, x: CGFloat, y: CGFloat, color: UIColor, superView: UIView, imageToUse: String? = nil, contentMode: UIViewContentMode = .ScaleAspectFill) {
        super.init()

        self.superView = superView

        self.backgroundColor = color

        self.setTranslatesAutoresizingMaskIntoConstraints(false)

        let panGestureRecognizer = UIPanGestureRecognizer()
        panGestureRecognizer.addTarget(self, action: "draggedView:")
        self.addGestureRecognizer(panGestureRecognizer)

        let widthConstraint = NSLayoutConstraint(item: self, attribute: .Width, relatedBy: .Equal,
            toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: width)
        self.addConstraint(widthConstraint)

        let heightConstraint = NSLayoutConstraint(item: self, attribute: .Height, relatedBy: .Equal,
            toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: height)
        self.addConstraint(heightConstraint)

        xPosConstraint = NSLayoutConstraint(item: self, attribute: .CenterX, relatedBy: .Equal,
            toItem: superView, attribute: .Leading, multiplier: 1.0, constant: x)

        yPosConstraint = NSLayoutConstraint(item: self, attribute: .CenterY, relatedBy: .Equal,
            toItem: superView, attribute: .Top, multiplier: 1.0, constant: y)

        if imageToUse != nil {
            if let image = UIImage(named: imageToUse!) {
                let imageView = UIImageView(image: image)
                imageView.contentMode = contentMode
                imageView.clipsToBounds = true
                imageView.setTranslatesAutoresizingMaskIntoConstraints(false)
                self.addSubview(imageView)
                self.addConstraint(NSLayoutConstraint(item: imageView, attribute: .Left, relatedBy: .Equal, toItem: self, attribute: .Left, multiplier: 1.0, constant: 0))
                self.addConstraint(NSLayoutConstraint(item: imageView, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1.0, constant: 0))
                self.addConstraint(NSLayoutConstraint(item: imageView, attribute: .Right, relatedBy: .Equal, toItem: self, attribute: .Right, multiplier: 1.0, constant: 0))
                self.addConstraint(NSLayoutConstraint(item: imageView, attribute: .Bottom, relatedBy: .Equal, toItem: self, attribute: .Bottom, multiplier: 1.0, constant: 0))
            }
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func moveByDeltaX(deltaX: CGFloat, deltaY: CGFloat) {
        xPosConstraint.constant += deltaX
        yPosConstraint.constant += deltaY
    }

    func draggedView(sender:UIPanGestureRecognizer){
        if let dragView = sender.view as? DraggableView {
            superView.bringSubviewToFront(dragView)
            var translation = sender.translationInView(superView)
            sender.setTranslation(CGPointZero, inView: superView)
            dragView.moveByDeltaX(translation.x, deltaY: translation.y)
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何实现多个PanGestures(可拖动视图)? 的相关文章

随机推荐

  • 使用 C# 删除换行符

    我从名为 Description 的数据库字段获取一个字符串 它有换行符 它看起来像这样 项目标题 此处为描述 这是项目的描述 我怎样才能删除换行符 我尝试了以下功能 但它不起作用 public string FormatComments
  • 设置div动态填充剩余高度?

    所以 我的代码类似于 div style width 100 min height 1 display block background color 000 img src header image svg div div Some con
  • 在 Python 中检测 NUMLOCK / CAPSLOCK / SCRLOCK 按键/按键

    在我正在开发的游戏中 我想检测NUMLOCK keypress or keyup 就像在按下时注册一个 回调 函数 我并不是要求阅读它state在某一特定时刻 我已经可以做到了 https github com MestreLion pyr
  • 有没有办法在设置类的任何属性时调用方法?

    因此 我想做的是在设置 C 类中的任何属性时调用单个 propertyWasSet 函数 相反 在获取属性时调用 propertyWasGot 我还想知道调用了哪个属性的 get 我想维护一个 设置 属性的字典 并检查 获取 操作是否已设置
  • Angular 库包依赖项

    我使用 CLI 创建并捆绑了一个 Angular 7 2 0 库 ng g 库 MyLibrary ng 构建 MyLibrary 这给了我my libary umd js我需要的捆绑包 目前 所有依赖项都作为peerDependency
  • 如何在同一场战争的多个 jar 中使用相同的 CamelContext

    我使用的是camel 2 16 2 我需要在多个jar 中使用一个 CamelContext 因为我需要将所有 Camel 路由器放入一个 CamelContext 中 所以我的战争将把所有这些罐子作为 Maven 工件 请告诉我如何处理上
  • 设施位置的动态规划算法

    沿着一条线 在位置 a 1 a 2 a n 处有 n 栋房屋 我们希望沿着同一条线设置移动便盆 以便每间房屋都位于至少一个移动便盆的距离 R 内 这些便携式便盆仅限于指定位置 b 1 b 2 b m 令 c i 为在位置 b i 设置移动便
  • openapi-generator 复制 swagger-ui 中的端点

    openapi generator maven plugin 版本 6 3 0 在 Spring Boot 3 应用程序中配置如下
  • 分区比排序更容易吗?

    这是一个在我脑海里徘徊了一段时间的问题 假设我有一个项目列表和它们的等价关系 并且比较两个项目需要恒定的时间 我想退回一部分物品 例如链表的列表 每个链表包含所有等效项 实现此目的的一种方法是将等价性扩展到项目的排序并对其进行排序 使用排序
  • 在无向图中记录 DFS 搜索中的前驱

    我试图使用此线程中的代码 提升DFS back edge https stackoverflow com questions 19346820 boost dfs back edge 19391511 noredirect 1 commen
  • String.count() 是如何工作的? [复制]

    这个问题在这里已经有答案了 我是 python 和学习的新手 如所给出的here https www tutorialspoint com python string count htm count 方法在字符串上使用时给出子字符串在字符串
  • 如何为Java类创建两个接口,一个只读,一个读写?

    我正在用 Java 为一款两人纸牌游戏编写一个游戏引擎 我的学生将为该游戏编写 AI 玩家 人工智能玩家将轮流在他们面前的 桌子 的 场地 上打牌 他们可以用自己场上的牌攻击对方场上的牌 卡片可以面朝上或面朝下 GameEngine 类允许
  • 如何根据构建变体更改 AndroidManifest.xml 文件?

    我有一个具有多个构建变体的应用程序 这些变体用于为不同公司构建同一应用程序的版本 因此 我有几个不同的变体来构建不同的应用程序 com acme app1 com schmoe app2 com yop app3 etc build gra
  • 指定服务返回字段的最佳方法

    我们使用 Java EE 7 和 WildFly 9 来开发移动 Web 应用程序的自定义后端 后端是一个经典的三层系统 具有通信逻辑 JAX RS 业务逻辑 Session EJB 和持久层 Hibernate 业务逻辑层由一组服务组成
  • 压缩输出与 Go to Ruby 实现不同

    我正在实现一个程序 将文件压缩为 git blob 并适当存储它 我有一个红宝石参考实现 https github com sgen git deflate blob bugfix deflate deflate file这是基于git 书
  • “找不到主类。程序将退出”

    我正在尝试运行 SQuirreL SQL 我已经下载并安装了它 但是当我尝试运行它时 我收到以下错误消息 Java 虚拟机启动器 无法找到主类 程序将会退出 我明白了这一点 但我不知道如何解决它 有什么帮助吗 更多信息 我使用的是 Wind
  • Win32_Product 的替代品?

    尝试查询后Win32 Product寻找软件版本时 我无法理解为什么结果如此缓慢 比查询慢15倍Win32 service or Win32 process 所以来这里看看我是否遗漏了什么 我发现其他人也报告了同样的问题 而这个articl
  • 如何查看 JDBC / MySQL 的 TRANSACTION_REPEATABLE_READ 操作?

    我的计算机上当前运行 MySQL 服务器 5 7 16 并且此服务器上名为 Sakila 的数据库中有此示例行 mysql gt SELECT FROM actor WHERE last name tugay actor id first
  • 使用 vba 查看和隐藏 Excel 中的列

    我有一个工作表 其中 B G 列中包含值 在单元格 A1 的同一张表中 我使用数据验证创建了一个下拉列表 其中包含 A B 和 C 等值 我需要的是 当我选择单元格值 A 时 B C 列需要可见 而其他列应该对 D G 隐藏 以同样的方式
  • 如何实现多个PanGestures(可拖动视图)?

    我想要几个可以拖放的对象 这是我移动一个对象的代码 在 vacawama 的帮助下 import UIKit class ViewController UIViewController IBOutlet weak var panView U