My swift code below declares 2 imageviews and 2 uipangesutres. This code just ouptus 2 imageviews that can move around. What I want to do is create 1 uipangesture and have it apply to all of the imageviews. I am think there is a more efficent way to do this. Instead of declaring a var for every thing that needs to be move around in the view controller.
import UIKit
class ViewController: UIViewController {
var image1 = UIImageView(); var image2 = UIImageView()
var image1Pan = UIPanGestureRecognizer()
var image2Pan = UIPanGestureRecognizer()
override func viewDidLoad() {
super.viewDidLoad()
image1Pan = UIPanGestureRecognizer(target: self, action: #selector(ViewController.moveMethod))
image1.addGestureRecognizer(image1Pan)
image2Pan = UIPanGestureRecognizer(target: self, action: #selector(ViewController.moveMethod))
image2.addGestureRecognizer(image2Pan)
[image1,image2].forEach{
$0.isUserInteractionEnabled = true
view.addSubview($0)
$0.translatesAutoresizingMaskIntoConstraints = false
}
// Do any additional setup after loading the view.
NSLayoutConstraint.activate ([
image1.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant :0),
image1.topAnchor.constraint(equalTo: view.topAnchor, constant : 50),
image1.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.10, constant: 0),
image1.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.40, constant: 0),
image1.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant : 0),
image2.topAnchor.constraint(equalTo: view.topAnchor, constant : 50),
image2.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.10, constant: 0),
image2.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.40, constant: 0),
image2.leadingAnchor.constraint(equalTo: image1.trailingAnchor, constant : 0),
])
image1.backgroundColor = .blue
image2.backgroundColor = .brown
}
@objc func moveMethod(_ sender: UIPanGestureRecognizer){
let tranistioon = sender.translation(in: self.view)
sender.view!.center = CGPoint(x: sender.view!.center.x + tranistioon.x, y: sender.view!.center.y + tranistioon.y)
sender.setTranslation(CGPoint.zero,in: self.view) }}
A Gesture Recognizer (such as `UIPanGestureRecognizer) is an object, not a property.
It probably seems obvious that this code:
// create a NEW instance of UIImageView each time throught the loop
let imgView = UIImageView()
var x: CGFloat = 50
[UIColor.red, UIColor.green, UIColor.blue].forEach {
// add imgView to self.view
view.addSubview(imgView)
// set imgView's properties
imgView.backgroundColor = $0
imgView.frame = CGRect(x: x, y: 100, width: 50, height: 50)
x += 100
}
Will not result in 3 image views. It will give you one image view with a blue background with a frame of (250.0, 100.0, 50.0, 50.0)
. That's because you only created one image view, and you are only changing its properties each time through the loop.
To get three image views (red, green and blue backgrounds) spaced 50-pts apart, you would need to do this:
var x: CGFloat = 50
[UIColor.red, UIColor.green, UIColor.blue].forEach {
// create a NEW instance of UIImageView each time throught the loop
let imgView = UIImageView()
// add it to self.view
view.addSubview(imgView)
// set its properties
imgView.backgroundColor = $0
imgView.frame = CGRect(x: x, y: 100, width: 50, height: 50)
x += 100
}
That's why you need to take the same approach with Gesture Recognizers. You need a new one for each object you wish to add it to.
Depending on what all you will be doing, you can simplify things a bit:
[image1, image2].forEach {
$0.isUserInteractionEnabled = true
view.addSubview($0)
$0.translatesAutoresizingMaskIntoConstraints = false
// create a NEW instance of UIPanGestureRecognizer
let pg = UIPanGestureRecognizer(target: self, action: #selector(ViewController.moveMethod))
// add it to $0 (an image view)
$0.addGestureRecognizer(pg)
}