问题
I have been trying to animate a UITextField so that its y position increases by 50px. Basically, it moves up by fifty pixels. This is my code:
@IBAction func textField(sender: AnyObject) {
let x = self.pw.frame.origin.x
let y = self.pw.frame.origin.y + 100
UIView.animateWithDuration(0.5, delay: 0, options: nil, animations: {
self.pw.frame = CGRectMake(x, y, self.pw.frame.size.width, self.pw.frame.size.height)
}, completion: nil)
It is in a textField's delegate. This code is run when the UITextField is tapped.
This code, sadly, does not do what I want it to. When run, it moves the text field up by 50 pixels but then moves it right back down. It does not finish with it up in what is supposed to be its final position.
回答1:
As mentioned in the comments, you should not manually modify frames when you have autolayout constraints installed. Instead you need to change your constraints to reflect the animation's end result.
The following is a minimal working example. It creates a button and a text field and initially positions the text field 58 points below the end of the button. When you tap the button, the constant on the text field's top spacing constraint is decreased from 58 to 8 to move the text field up.
class ViewController: UIViewController {
var textFieldTopSpacingConstraint: NSLayoutConstraint?
override func viewDidLoad() {
super.viewDidLoad()
// Create the button
let button = UIButton.buttonWithType(.System) as! UIButton
button.setTranslatesAutoresizingMaskIntoConstraints(false)
button.setTitle("Tap me!", forState: .Normal)
button.addTarget(self, action: "buttonTapped", forControlEvents: .TouchUpInside)
view.addSubview(button)
// Create the text field
let textField = UITextField()
textField.placeholder = "Enter text here"
textField.setTranslatesAutoresizingMaskIntoConstraints(false)
view.addSubview(textField)
let views: [NSObject: AnyObject] = ["button": button, "textField": textField]
// Layout the button
view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[button]-|", options: nil, metrics: nil, views: views))
view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-20-[button(44)]", options: nil, metrics: nil, views: views))
// Layout the text field and remember its top spacing constraint
view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[textField]-|", options: nil, metrics: nil, views: views))
textFieldTopSpacingConstraint = NSLayoutConstraint(item: textField, attribute: .Top, relatedBy: .Equal,
toItem: button, attribute: .Bottom, multiplier: 1, constant: 58) // The text field starts 58 points below the end of the button
view.addConstraint(textFieldTopSpacingConstraint!)
}
func buttonTapped() {
// Change to constant on the top spacing constraint to move the text field up
UIView.animateWithDuration(0.5) {
self.textFieldTopSpacingConstraint?.constant = 8 // The text field now starts 8 points below the end of the button
self.view.layoutIfNeeded()
}
}
}
When you have your constraints set up through Interface Builder you can create an outlet for the top spacing constraint in your view controller and use that to modify the text field's top space.
回答2:
You are expecting the pw
frame to move by 100, but instead on the device/simulator it is only 50, that is due to the difference between pixels and points (have a look here).
As for the frame going back to its original position, you should check the rest of your code.
来源:https://stackoverflow.com/questions/31904573/dynamically-moving-animating-a-uitextfield