I am really struggling to find tutorials online as well as already answered questions (I have tried them and they don't seem to work). I have a UIImageView that I have in the centre of my view. I am currently able to tap and drag this wherever I want on screen. I want to be able to pinch to scale and rotate this view. How do I achieve this? I have tried the code for rotation below but it doesn't seem to work? Any help will be a massive help and marked as answer. Thank you guys.
import UIKit
class DraggableImage: UIImageView {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.backgroundColor = .blue
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
self.backgroundColor = .green
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let position = touch.location(in: superview)
center = CGPoint(x: position.x, y: position.y)
}
}
}
class CVController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let rotateGesture = UIRotationGestureRecognizer(target: self, action: #selector(rotateAction(sender:)))
firstImageView.addGestureRecognizer(rotateGesture)
setupViews()
}
func rotateAction(sender: UIRotationGestureRecognizer) {
let rotatePoint = sender.location(in: view)
let firstImageView = view.hitTest(rotatePoint, with: nil)
firstImageView?.transform = (firstImageView?.transform.rotated(by: sender.rotation))!
sender.rotation = 0
}
let firstImageView: DraggableImage = {
let iv = DraggableImage()
iv.backgroundColor = .red
iv.isUserInteractionEnabled = true
return iv
}()
func setupViews() {
view.addSubview(firstImageView)
let firstImageWidth: CGFloat = 50
let firstImageHeight: CGFloat = 50
firstImageView.frame = CGRect(x: (view.frame.width / 2) - firstImageWidth / 2, y: (view.frame.height / 2) - firstImageWidth / 2, width: firstImageWidth, height: firstImageHeight)
}
}
You have a some problems in your code. First you need to add the UIGestureRecognizerDelegate to your view controller and make it your gesture recognizer delegate. and add the shouldRecognizeSimultaneously method and return true. Second when applying the scale you need to save the transform when the pinch begins and apply the scale in top of it:
class DraggableImageView: UIImageView {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
backgroundColor = .blue
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
backgroundColor = .green
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
if let position = touches.first?.location(in: superview){
center = position
}
}
}
class ViewController: UIViewController, UIGestureRecognizerDelegate {
var identity = CGAffineTransform.identity
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
setupViews()
let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(scale))
let rotationGesture = UIRotationGestureRecognizer(target: self, action: #selector(rotate))
pinchGesture.delegate = self
rotationGesture.delegate = self
view.addGestureRecognizer(pinchGesture)
view.addGestureRecognizer(rotationGesture)
}
let firstImageView: DraggableImageView = {
let iv = DraggableImageView()
iv.backgroundColor = .red
iv.isUserInteractionEnabled = true
return iv
}()
func setupViews() {
view.addSubview(firstImageView)
let firstImageWidth: CGFloat = 50
let firstImageHeight: CGFloat = 50
firstImageView.frame = CGRect(x: view.frame.midX - firstImageWidth / 2, y: view.frame.midY - firstImageWidth / 2, width: firstImageWidth, height: firstImageHeight)
}
@objc func scale(_ gesture: UIPinchGestureRecognizer) {
switch gesture.state {
case .began:
identity = firstImageView.transform
case .changed,.ended:
firstImageView.transform = identity.scaledBy(x: gesture.scale, y: gesture.scale)
case .cancelled:
break
default:
break
}
}
@objc func rotate(_ gesture: UIRotationGestureRecognizer) {
firstImageView.transform = firstImageView.transform.rotated(by: gesture.rotation)
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
来源:https://stackoverflow.com/questions/42965235/swift-3-how-do-i-pinch-to-scale-and-rotate-uiimageview