import UIKit import PlaygroundSupport import SnapKit var horzPadding = 20 var vertPadding = 20 class ActionTarget { let closure: () -> () init(closure: @escaping () -> ()) { self.closure = closure } @objc func action(val: Int) { closure() } } // new up elements let view = UIView() view.backgroundColor = UIColor.white let vc = UIViewController() vc.view = view let firstNameLabel = UILabel() firstNameLabel.text = "First Name" view.addSubview(firstNameLabel) let firstNameField = UITextField() firstNameField.borderStyle = .roundedRect view.addSubview(firstNameField) let lastNameLabel = UILabel() lastNameLabel.text = "Last Name" view.addSubview(lastNameLabel) let lastNameField = UITextField() lastNameField.borderStyle = .roundedRect view.addSubview(lastNameField) let horzSlider = UISlider() horzSlider.minimumValue = 0 horzSlider.maximumValue = 50 horzSlider.value = Float(horzPadding) view.addSubview(horzSlider) let vertSlider = UISlider() vertSlider.minimumValue = 0 vertSlider.maximumValue = 50 vertSlider.value = Float(vertPadding) view.addSubview(vertSlider) let animButton = UIButton() animButton.backgroundColor = UIColor.green animButton.setTitle("Animate", for: UIControlState.normal) view.addSubview(animButton) // setup constraints var leftConstraint: ConstraintMakerEditable? = nil var rightConstraint: ConstraintMakerEditable? = nil var topConstraints: [Constraint] = [] horzSlider.snp.makeConstraints { (make) in make.top.equalTo(vc.topLayoutGuide.snp.bottom).offset(20).constraint make.left.equalTo(view).offset(horzPadding) make.right.equalTo(view).offset(-horzPadding) } vertSlider.snp.makeConstraints { (make) in make.top.equalTo(horzSlider.snp.bottom).offset(20).constraint make.left.equalTo(view).offset(horzPadding) make.right.equalTo(view).offset(-horzPadding) } firstNameLabel.snp.makeConstraints { (make) -> Void in topConstraints.append(make.top.equalTo(vertSlider.snp.bottom).offset(vertPadding).constraint) leftConstraint = make.left.equalTo(view).offset(horzPadding) rightConstraint = make.right.equalTo(view).offset(-horzPadding) } firstNameField.snp.makeConstraints { (make) -> Void in make.top.equalTo(firstNameLabel.snp.bottom) make.left.equalTo(firstNameLabel) make.right.equalTo(firstNameLabel) } lastNameLabel.snp.makeConstraints { (make) in topConstraints.append(make.top.equalTo(firstNameField.snp.bottom).offset(vertPadding).constraint) make.left.equalTo(firstNameLabel) make.right.equalTo(firstNameLabel) } lastNameField.snp.makeConstraints { (make) in make.top.equalTo(lastNameLabel.snp.bottom) make.left.equalTo(firstNameLabel) make.right.equalTo(firstNameLabel) } animButton.snp.makeConstraints { (make) in topConstraints.append(make.top.equalTo(lastNameField.snp.bottom).offset(vertPadding).constraint) make.left.equalTo(firstNameLabel) make.right.equalTo(firstNameLabel) make.height.equalTo(40) } // wire up let slideXTarget = ActionTarget() { horzPadding = Int(horzSlider.value) print ("horz: \(horzPadding)") // Route 1: leftConstraint?.constraint.update(offset: horzPadding) rightConstraint?.constraint.update(offset: -horzPadding) // Route 2: // firstNameLabel.snp.updateConstraints { (make) -> Void in // make.left.equalTo(view).offset(horzPadding) // make.right.equalTo(view).offset(-horzPadding) // } } let slideYTarget = ActionTarget() { vertPadding = Int(vertSlider.value) for var c in topConstraints { c.update(offset: vertPadding) } } let animatedTarget = ActionTarget() { var newHorzPadding: Int = 0 if (horzPadding == 50) { newHorzPadding = 0 } else { newHorzPadding = 50 } leftConstraint?.constraint.update(offset: newHorzPadding) rightConstraint?.constraint.update(offset: -newHorzPadding) view.setNeedsLayout() UIView.animate(withDuration: 0.2, animations: { () -> Void in view.layoutIfNeeded() }, completion: { (value: Bool) in horzPadding = newHorzPadding horzSlider.value = Float(horzPadding) }) } horzSlider.addTarget(slideXTarget, action: #selector(ActionTarget.action), for: .valueChanged) vertSlider.addTarget(slideYTarget, action: #selector(ActionTarget.action), for: .valueChanged) animButton.addTarget(animatedTarget, action: #selector(ActionTarget.action), for: .touchUpInside) PlaygroundPage.current.liveView = vc vc