如何实现多个PanGestures(可拖动的意见)? [英] How to implement multiple PanGestures (Draggable views)?
问题描述
我想有几个对象,我可以拖放。
I want to have several objects that I can drag and drop.
下面是我的code移动一个对象(从@vacawama很大的帮助):
Here's my code for moving one object (with lot of help from @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.
}
}
我想在我的项目中多个对象:
I want to have more objects in my project:
@IBOutlet weak var panView2: UIView!
@IBOutlet weak var panView3: UIView!
@IBOutlet weak var panView4: UIView!
...
那么,什么是实现这个以这样一种方式,我可以有最简单的方法多个 PANVIEW
,我可以(当时的)移动独立身边?
So, what is the easiest way to implement this in such way that I can have multiple panView
which I can move independently around (one at the time)?
推荐答案
如果您正在使用的自动布局的,你不应该仅仅通过改变其中心移动的视图。任何导致的自动布局的运行将移动您的视图回到它原来的位置。
If you are using Auto Layout, you shouldn't just move a view by altering its center. Anything that causes Auto Layout to run will move your view back to its original position.
下面是 DraggableView
称为一个新的类,它使用作品的实现的自动布局的以提供可拖动的意见。它的宽度,高度,X位置,视图的Y位置创建了code约束。它使用自己的 UIPanGestureRecognizer
来使视图拖动。
Here is an implementation of a new class called DraggableView
that works with Auto Layout to provide views that can be dragged. It creates constraints in code for the width, height, X position, and Y position of the view. It uses its own UIPanGestureRecognizer
to allow the view to be dragged.
的 DraggableView.swift 的能投进需要拖动意见任何项目。看看的 ViewController.swift 的下面,看看它是多么容易使用。
DraggableView.swift can be dropped into any project that needs draggable views. Take a look at ViewController.swift below to see how easy it is to use.
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)
}
}
更新:
下面是一个版本的 DraggableView.swift 支持图像作为一个子视图。
Here is a version of DraggableView.swift that supports images as a subview.
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)
}
}
}
这篇关于如何实现多个PanGestures(可拖动的意见)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!