Динамическое перемещение (анимация) UITextField

Я пытался анимировать UITextField, чтобы его позиция y увеличивалась на 50 пикселей. В основном он перемещается на пятьдесят пикселей вверх. Это мой код:

@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)

Он находится в делегате textField. Этот код запускается при касании UITextField.

К сожалению, этот код делает не то, что я хочу. При запуске он перемещает текстовое поле вверх на 50 пикселей, но затем перемещает его обратно вниз. Он не заканчивает тем, что находится в том, что должно быть его окончательным положением.


person Daniel    schedule 09.08.2015    source источник
comment
Есть ли у вас что-нибудь еще, что позиционирует текстовое поле в вашем коде? Может быть, в layoutSubViews супервизора? Есть ли маска автоматического изменения размера или ограничения автоматического размещения?   -  person hennes    schedule 09.08.2015
comment
@hennes - у меня есть ограничения. Должен ли я вручную устанавливать их в viewDidLoad ()?   -  person Daniel    schedule 09.08.2015
comment
Вы не должны вручную манипулировать фреймами, если у вас установлены ограничения. Вам необходимо выполнить анимацию, изменив ограничения. Не могли бы вы поделиться ограничениями, которые вы применили к текстовому полю?   -  person hennes    schedule 09.08.2015
comment
@hennes - горизонтально (в поле зрения) и вертикальный интервал до UIButton   -  person Daniel    schedule 09.08.2015


Ответы (2)


Как упоминалось в комментариях, вам не следует вручную изменять фреймы, если у вас установлены ограничения автоматического размещения. Вместо этого вам нужно изменить ограничения, чтобы отразить конечный результат анимации.

Ниже приведен минимальный рабочий пример. Он создает кнопку и текстовое поле и первоначально размещает текстовое поле на 58 пунктов ниже конца кнопки. Когда вы нажимаете кнопку, константа ограничения верхнего интервала текстового поля уменьшается с 58 до 8 для перемещения текстового поля вверх.

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()
        }
    }

}

Когда ваши ограничения настроены через Interface Builder, вы можете создать выход для ограничения верхнего интервала в вашем контроллере представления и использовать его для изменения верхнего пространства текстового поля.

person hennes    schedule 10.08.2015

Вы ожидаете, что рамка pw переместится на 100, но вместо этого на устройстве / симуляторе это только 50, что связано с разницей между пикселями и точками (см. здесь). Что касается возврата кадра в исходное положение, вам следует проверить остальную часть кода.

person ielyamani    schedule 09.08.2015
comment
Он ничего не говорит о 100 вместо 50 в своем вопросе, или я ошибаюсь? - person hennes; 09.08.2015