UITextField text jumps when animating width constraint

后端 未结 1 986
孤城傲影
孤城傲影 2021-01-14 20:28

I\'m experiencing a glitch where my UITextField\'s text jumps to its final position (it doesn\'t animate) when animating the textfield\'s width constraint. Take a look at th

相关标签:
1条回答
  • 2021-01-14 21:06

    Solution Demo

    I've found a working solution. It feels a little hackish but it works. Here is a gif of the final result. Notice that helloWorldTextField has a blue border to show its location within the second textfield behind it.

    Instructions

    Make two textfields: helloWorldTextField (the original from the question) and borderTextField (a new textfield). Remove helloWorldTextFields's border and background color. Keep borderTextField's border and background color. Center helloWorldTextField within borderTextField. Then animate the width of borderTextField.

    Github link and Code

    Here is the project on Github: https://github.com/starkindustries/ConstraintAnimationTest

    Here is the code within MyViewController class. Everything else is setup in the storyboard which can be viewed on Github at the link above.

    class MyViewController: UIViewController {
        
        // Hello World TextField Border var
        @IBOutlet weak var borderTextFieldWidth: NSLayoutConstraint!
        
        // Button Vars
        @IBOutlet weak var myButton: UIButton!
        var grow: Bool = false
        
        func animateGrowShrinkTextFields(grow: Bool, duration: TimeInterval) {
            if grow {
                UIView.animate(withDuration: duration, animations: {
                    self.borderTextFieldWidth.constant = 330
                    self.view.layoutIfNeeded()
                }, completion: { (finished: Bool) in
                    print("Grow animation complete!")
                })
            } else {
                UIView.animate(withDuration: duration, animations: {
                    self.borderTextFieldWidth.constant = 115
                    self.view.layoutIfNeeded()
                }, completion: { (finished: Bool) in
                    print("Shrink animation complete!")
                })
            }
        }
        
        @IBAction func toggle(){
            let duration: TimeInterval = 1.0
            grow = !grow
            let title = grow ? "Shrink" : "Grow"
            myButton.setTitle(title, for: UIControlState.normal)
            animateGrowShrinkTextFields(grow: grow, duration: duration)
        }
    }
    

    Notes and References

    What led me to this solution was @JimmyJames's comment: "You are just animating the UITextField width, but the content inside is not animated."

    I researched how to animate font changes and came across this question: Is there a way to animate changing a UILabel's textAlignment?

    In that question @CSmith mentioned that "you can animate the FRAME, not the textAlignment" https://stackoverflow.com/a/19251634/2179970

    The accepted answer in that question suggests to use a UILabel within another frame. https://stackoverflow.com/a/19251735/2179970

    Hope this helps anyone else who comes across this problem. If anyone has another way to solve this, please post a comment or another answer. Thanks!

    0 讨论(0)
提交回复
热议问题