Skip to content

Instantly share code, notes, and snippets.

@chunkyguy
Created December 12, 2022 22:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chunkyguy/e0acac64fcc027f917b9b4b7d02830a9 to your computer and use it in GitHub Desktop.
Save chunkyguy/e0acac64fcc027f917b9b4b7d02830a9 to your computer and use it in GitHub Desktop.
MoveMe with layoutSubviews
import UIKit
struct Colors {
static var normal = UIColor.blue
static var selected = UIColor.red
}
extension CGPoint {
static func add(_ left: CGPoint, _ right: CGPoint) -> CGPoint {
return CGPoint(x: left.x + right.x, y: left.y + right.y)
}
}
class MoveMeView: UIView {
struct Model {
var color = Colors.normal
var scale: CGFloat
var position = CGPoint.zero
}
private var model: Model! {
didSet {
// request layoutSubviews to be called again
setNeedsLayout()
}
}
private let cardView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: 100, height: 100)))
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(cardView)
backgroundColor = .lightGray
let dragGesture = UIPanGestureRecognizer(target: self, action: #selector(onDrag))
addGestureRecognizer(dragGesture)
}
required init?(coder: NSCoder) {
fatalError()
}
override func layoutSubviews() {
super.layoutSubviews()
if model == nil {
model = Model(color: .blue, scale: 1.0, position: center)
}
cardView.backgroundColor = model.color
cardView.center = model.position
cardView.transform = CGAffineTransform(scaleX: model.scale, y: model.scale)
}
@objc func onDrag(_ panGestureRecognizer: UIPanGestureRecognizer) {
switch panGestureRecognizer.state {
case .began:
model.color = Colors.normal
model.scale = 1.2
UIView.animate(withDuration: 0.3, delay: 0, options: [.beginFromCurrentState]) {
self.layoutIfNeeded()
}
case .changed:
model.color = Colors.selected
let translation = panGestureRecognizer.translation(in: self)
model.position = CGPoint.add(translation, model.position)
panGestureRecognizer.setTranslation(.zero, in: self)
case .ended:
model.color = Colors.normal
model.scale = 1.0
UIView.animate(withDuration: 0.3, delay: 0, options: [.beginFromCurrentState]) {
self.layoutIfNeeded()
}
default:
model.color = Colors.normal
}
}
}
import UIKit
class ViewController: UIViewController {
lazy var movmeVw = MoveMeView(
frame: CGRect(
origin: .zero,
size: CGSize(width: 100, height: 100)
)
)
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(movmeVw)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
movmeVw.frame = view.frame
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment