Skip to content

Instantly share code, notes, and snippets.

@sketchytech
Last active August 28, 2023 23:11
Show Gist options
  • Save sketchytech/27e46e3f6abc083ee9749835e34cb125 to your computer and use it in GitHub Desktop.
Save sketchytech/27e46e3f6abc083ee9749835e34cb125 to your computer and use it in GitHub Desktop.
Using Auto Layout Constraints for Drag, Pinch, Zoom and Tap
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
@shoaibahmaddx
Copy link

My UILabel jumps to initial position when I change its font programmatically. I have a button for that. What could be wrong?

@sketchytech
Copy link
Author

My UILabel jumps to initial position when I change its font programmatically. I have a button for that. What could be wrong?

I wrote this code a long time ago, so I'm working from memory here, but the jumping issue occurs because the constraint values are not updated, or a refresh of the values is triggered. This is the reason for all the .changed cases. I'd look at what's happening in the redrawing of the label when the font changes. It might be being thrown back to its original position because the whole thing is being redrawn.

@shoaibahmaddx
Copy link

My UILabel jumps to initial position when I change its font programmatically. I have a button for that. What could be wrong?

I wrote this code a long time ago, so I'm working from memory here, but the jumping issue occurs because the constraint values are not updated, or a refresh of the values is triggered. This is the reason for all the .changed cases. I'd look at what's happening in the redrawing of the label when the font changes. It might be being thrown back to its original position because the whole thing is being redrawn.

Thank you so much @sketchytech. I managed to achieve that by updating constraint constant value and it is now working fine.

@sketchytech
Copy link
Author

My UILabel jumps to initial position when I change its font programmatically. I have a button for that. What could be wrong?

I wrote this code a long time ago, so I'm working from memory here, but the jumping issue occurs because the constraint values are not updated, or a refresh of the values is triggered. This is the reason for all the .changed cases. I'd look at what's happening in the redrawing of the label when the font changes. It might be being thrown back to its original position because the whole thing is being redrawn.

Thank you so much @sketchytech. I managed to achieve that by updating constraint constant value and it is now working fine.

Brilliant, @shoaibahmaddx thanks for taking the time to add the update, really pleased it worked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment