设置宽度约束动画时,UITextField文本会跳转 [英] UITextField text jumps when animating width constraint

查看:105
本文介绍了设置宽度约束动画时,UITextField文本会跳转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个小故障,当为文本字段的宽度约束设置动画时,我的UITextField的文本跳至其最终位置(不设置动画)。看看这个gif:





何时点击增长按钮,文本字段的宽度增加。但是 hello world立即跳到中心,而不是在中心滑动。轻按缩小按钮后, hello world将立即跳回左侧。



我的动画功能如下:

  func animateGrowShrinkTextFields(grow :Bool){
如果增长{
UIView.animate(withDuration:0.5,动画:{
self.widthConstraint.constant = 330
self.view.layoutIfNeeded()
},完成:无)
}其他{
UIView.animate(withDuration:0.5,动画:{
self.widthConstraint.constant = 100
self.view.layoutIfNeeded ()
},完成:无)
}
}

我尝试了以下列表建议;


  1. 我叫 self.view.layoutIfNeeded() self.helloWorldTextField.layoutIfNeeded()在此答案中建议的动画块之前和之内:



    说明



    创建两个文本字段: helloWorldTextField (问题的原始内容)和 borderTextField (新文本字段)。删除 helloWorldTextFields 的边框和背景颜色。保留 borderTextField 的边框和背景颜色。在 borderTextField 中将 helloWorldTextField 居中。然后为 borderTextField 的宽度设置动画。



    Github链接和代码



    这是Github上的项目: https://github.com/ starkindustries / ConstraintAnimationTest



    这是MyViewController类中的代码。其他所有内容都在情节提要中进行了设置,可在上述链接的Github上查看。

      class MyViewController:UIViewController {

    // Hello World TextField Border var
    @IBOutlet弱var borderTextFieldWidth:NSLayoutConstraint!

    //按钮变量
    @IBOutlet弱var myButton:UIButton!
    var grow:Bool = false

    func animateGrowShrinkTextFields(grow:Bool,duration:TimeInterval){
    if grow {
    UIView.animate(withDuration:持续时间,动画:{{
    self.borderTextFieldWidth.constant = 330
    self.view.layoutIfNeeded()
    },完成:{(完成:Bool)在
    print(完成动画制作! )
    })
    }否则{
    UIView.animate(withDuration:持续时间,动画:{
    self.borderTextFieldWidth.constant = 115
    self.view.layoutIfNeeded ()
    },完成:{(完成:布尔)in
    print(收缩动画完成!)
    })
    }
    }

    @IBAction func toggle(){
    let持续时间:TimeInterval = 1.0
    grow =!grow
    let title = grow吗? 收缩:增长
    myButton.setTitle(标题,用于:UIControlState.normal)
    animateGrowShrinkTextFields(增长:生长,持续时间:持续时间)
    }
    }

    注释和参考



    导致我想到此解决方案的是@JimmyJames的评论:您只是在动画UITextField宽度,但是里面的内容没有动画。



    我研究了如何制作动画字体更改并遇到以下问题:有没有办法要动画化UILabel的textAlignment?



    在该问题中@CSmith提到您可以动画化FRAME,而不是textAlignment动画 https://stackoverflow.com/a/19251634/2179970



    在这个问题建议在另一个框架中使用UILabel。 https://stackoverflow.com/a/19251735/2179970



    <希望这可以帮助遇到此问题的其他任何人。如果有人有其他解决方法,请发表评论或其他答案。谢谢!


    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 this gif:

    When the "Grow" button is tapped, the textfield's width grows. But "hello world" jumps immediately to the center instead of gliding there. When the "Shrink" button is tapped, "hello world" jumps immediately back to the left.

    My animation function looks like this:

    func animateGrowShrinkTextFields(grow: Bool) {
        if grow {
            UIView.animate(withDuration: 0.5, animations: {
                self.widthConstraint.constant = 330
                self.view.layoutIfNeeded()
            }, completion: nil)
        } else {
            UIView.animate(withDuration: 0.5, animations: {
                self.widthConstraint.constant = 100
                self.view.layoutIfNeeded()
            }, completion: nil)
        }
    }
    

    I have tried the following list suggestions; none of them worked.

    1. I called self.view.layoutIfNeeded() and self.helloWorldTextField.layoutIfNeeded() before and within the animation block as suggested in this answer: https://stackoverflow.com/a/32996503/2179970
    2. I tried self.view.layoutSubviews and self.helloWorldTextField.layoutSubview as suggested in this answer: https://stackoverflow.com/a/30845306/2179970
    3. Also tried setNeedsLayout() UITextField text jumps iOS 9
    4. I even tried changing the font as suggested here: https://stackoverflow.com/a/35681037/2179970
    5. I tried resignFirstResponder (although though I never tap or edit the textfield in my tests, so it should not involve the firstResponder) as suggested here: https://stackoverflow.com/a/33334567/2179970
    6. I tried subclassing UITextField as seen here: https://stackoverflow.com/a/40279630/2179970
    7. I also tried using a UILabel and got the same jumpy result.

    The following question is also very similar to mine but does not have an answer yet: UITextfield text position not animating while width constraint is animated

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

    解决方案

    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!

    这篇关于设置宽度约束动画时,UITextField文本会跳转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆