Last active
October 17, 2024 17:48
-
-
Save sketchytech/27e46e3f6abc083ee9749835e34cb125 to your computer and use it in GitHub Desktop.
Using Auto Layout Constraints for Drag, Pinch, Zoom and Tap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import PlaygroundSupport | |
class ViewController: UIViewController { | |
var redView:UIView! | |
var movedRight:Bool = false | |
var verticalConstraint:NSLayoutConstraint! | |
var horizontalConstraint:NSLayoutConstraint! | |
var widthConstraint:NSLayoutConstraint! | |
var heightConstraint:NSLayoutConstraint! | |
var offSet:CGPoint! | |
var transform: CGAffineTransform! | |
var viewSize:CGSize! | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
// Do any additional setup after loading the view, typically from a nib. | |
redView = UIView(frame: CGRect(x: 100, y: 100, width: 200, height: 200)) | |
redView.backgroundColor = .red | |
view.addSubview(redView) | |
let taps = UITapGestureRecognizer(target: self, action: #selector(tap)) | |
redView.addGestureRecognizer(taps) | |
let drags = UIPanGestureRecognizer(target: self, action: #selector(drag)) | |
redView.addGestureRecognizer(drags) | |
let pinches = UIPinchGestureRecognizer(target: self, action: #selector(pinch)) | |
redView.addGestureRecognizer(pinches) | |
let rotates = UIRotationGestureRecognizer(target: self, action: #selector(rotate)) | |
redView.addGestureRecognizer(rotates) | |
redView.isUserInteractionEnabled = true | |
alignView(viewToConstrain: redView) | |
} | |
@objc func rotate(gest:UIRotationGestureRecognizer) { | |
// view.layoutIfNeeded() | |
let rotation = gest.rotation | |
if let viewToTransform = gest.view { | |
switch (gest.state) { | |
case .began: | |
transform = viewToTransform.transform | |
break; | |
case .changed: | |
viewToTransform.transform = transform.concatenating(CGAffineTransform(rotationAngle: rotation)) | |
break; | |
case .ended: | |
break; | |
default: | |
break; | |
} | |
} | |
} | |
// see http://stackoverflow.com/a/21803627/1694526 | |
@objc func drag(gest:UIPanGestureRecognizer) { | |
view.layoutIfNeeded() | |
let translation = gest.translation(in: self.view) | |
switch (gest.state) { | |
case .began: | |
offSet = CGPoint(x: horizontalConstraint.constant, y: verticalConstraint.constant) | |
break; | |
case .changed: | |
horizontalConstraint.constant = offSet.x + translation.x | |
verticalConstraint.constant = offSet.y + translation.y | |
view.layoutIfNeeded() | |
break; | |
case .ended: | |
break; | |
default: | |
break; | |
} | |
} | |
@objc func pinch(gest:UIPinchGestureRecognizer) { | |
view.layoutIfNeeded() | |
let scale = gest.scale | |
switch (gest.state) { | |
case .began: | |
viewSize = CGSize(width: widthConstraint.constant, height: heightConstraint.constant) | |
break; | |
case .changed: | |
widthConstraint.constant = viewSize.width * scale | |
heightConstraint.constant = viewSize.height * scale | |
view.layoutIfNeeded() | |
break; | |
case .ended: | |
break; | |
default: | |
break; | |
} | |
} | |
@objc func tap(gest:UITapGestureRecognizer) { | |
if movedRight { | |
self.view.layoutIfNeeded() | |
self.verticalConstraint.constant += 25 | |
UIView.animate(withDuration: 0.5){ | |
self.view.layoutIfNeeded() | |
} | |
movedRight = false | |
} | |
else { | |
self.view.layoutIfNeeded() | |
UIView.animate(withDuration: 0.5){ | |
self.horizontalConstraint.constant += 25 | |
self.view.layoutIfNeeded() | |
} | |
movedRight = true | |
} | |
} | |
func alignView(viewToConstrain:UIView) { | |
// a precaution | |
viewToConstrain.removeConstraints(viewToConstrain.constraints) | |
// enable AutoLayout | |
viewToConstrain.translatesAutoresizingMaskIntoConstraints = false | |
// set horizontal and vertical constraints | |
horizontalConstraint = viewToConstrain.centerXAnchor.constraint(equalTo: view.centerXAnchor) | |
horizontalConstraint.isActive = true | |
verticalConstraint = viewToConstrain.centerYAnchor.constraint(equalTo: view.centerYAnchor) | |
verticalConstraint.isActive = true | |
// set height and width anchors | |
heightConstraint = viewToConstrain.heightAnchor.constraint(equalToConstant: viewToConstrain.frame.height) | |
heightConstraint.isActive = true | |
widthConstraint = viewToConstrain.widthAnchor.constraint(equalToConstant: viewToConstrain.frame.width) | |
widthConstraint.isActive = true | |
} | |
} | |
let aVC = ViewController() | |
PlaygroundPage.current.liveView = aVC |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Brilliant, @shoaibahmaddx thanks for taking the time to add the update, really pleased it worked.