How do i position a view using Auto Layout anchors outside the screen to the right? I want to animate it later in to center position.
func setup(){
_ = firstNameTextField.anchor(nil,
left: view.leftAnchor,
bottom: lastnameTextField.topAnchor,
right: view.rightAnchor,
topConstant: 16,
leftConstant: 16,
bottomConstant: 8,
rightConstant: 16,
widthConstant: 0,
heightConstant: 46)
}
It can be beneficial to explicitly define your constraints, rather than using a "helper" func... it can make it easier for you to understand what's going on.
That said, you want the left
anchor of your field to be constrained to the right
anchor of your view, which will put it "off-screen". You can then change that to animate the field into view... "slide it in from the right".
To do that, create a "start" constraint and an "end" constraint:
// starting constraint will be leading edge of field 16-pts to the right of view's right edge (off-screen)
firstNameLeadingConstraintStart = firstNameTextField.leadingAnchor.constraint(equalTo: view.trailingAnchor, constant: 16.0)
// ending constraint will be leading edge of field 16-pts from view's left edge
firstNameLeadingConstraintEnd = firstNameTextField.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16.0)
To animate it into view:
// de-activate starting constraint
self.firstNameLeadingConstraintStart.isActive = false
// activate ending constraint
self.firstNameLeadingConstraintEnd.isActive = true
// animate the change
UIView.animate(withDuration: 0.75, animations: {
self.view.layoutIfNeeded()
})
Here is a basic example. It includes a button to trigger the animation:
class SampleViewController: UIViewController {
var firstNameTextField: UITextField = {
let v = UITextField()
v.translatesAutoresizingMaskIntoConstraints = false
v.borderStyle = .roundedRect
v.backgroundColor = .orange // to make it easy to see
return v
}()
var button: UIButton = {
let v = UIButton()
v.translatesAutoresizingMaskIntoConstraints = false
v.setTitle("Tap Me", for: .normal)
v.setTitleColor(.blue, for: .normal)
return v
}()
// constraint for starting position of field
var firstNameLeadingConstraintStart: NSLayoutConstraint!
// constraint for ending position of field
var firstNameLeadingConstraintEnd: NSLayoutConstraint!
override func viewDidLoad() {
view.addSubview(firstNameTextField)
NSLayoutConstraint.activate([
// top of field 16-pts from top of view
firstNameTextField.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16.0),
// width of field should be width of view minus 32 (16-pts padding on each side)
firstNameTextField.widthAnchor.constraint(equalTo: view.safeAreaLayoutGuide.widthAnchor, constant: -32.0),
// height of field 46-pts
firstNameTextField.heightAnchor.constraint(equalToConstant: 46.0),
])
// starting constraint will be leading edge of field 16-pts to the right of view's right edge (off-screen)
firstNameLeadingConstraintStart = firstNameTextField.leadingAnchor.constraint(equalTo: view.trailingAnchor, constant: 16.0)
// ending constraint will be leading edge of field 16-pts from view's left edge
firstNameLeadingConstraintEnd = firstNameTextField.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16.0)
// activate the starting constraint
firstNameLeadingConstraintStart.isActive = true
// add a button so we can trigger the animation
view.addSubview(button)
NSLayoutConstraint.activate([
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: view.centerYAnchor),
])
button.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)
}
func animateField() -> Void {
// de-activate starting constraint
self.firstNameLeadingConstraintStart.isActive = false
// activate ending constraint
self.firstNameLeadingConstraintEnd.isActive = true
// animate the change
UIView.animate(withDuration: 0.75, animations: {
self.view.layoutIfNeeded()
})
}
@objc func didTap(_ sender: Any) {
animateField()
}
}