UITextField: When beginning input, textfield bounc

2019-08-12 09:00发布

问题:

I've seen this with UITextView too. Clearly, I'm missing something pretty basic.

I've tried: - Setting textsize to small - UITextField: Setting 1 line, no resize - Removing the ability to move the texfield

import UIKit

class XViewController: UIViewController, UITextFieldDelegate, UIGestureRecognizerDelegate {

    // UI elements
    let cancelButton = UIButton()
    let okButton = UIButton()
    var image:UIImage?
    var previewImageView:UIImageView = UIImageView()
    let textField = UITextField()
    let tapGestureRecognizer = UITapGestureRecognizer()
    let textFieldTypingPositionY:CGFloat = 200
    var textFieldActualPositionY:CGFloat!
    let textFieldHeight:CGFloat = 40

    var draggingTextField:Bool = false

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        setupTextField()
    }

    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString text: String) -> Bool {
        let textFieldSize = textField.text!.characters.count
        let textSize = text.characters.count
        if text == "\n" && textFieldSize == 0 {
            // press return on empty textfield
            textField.text = ""
            hideTextField()
            return true
        } else if textFieldSize == 1 && text == "" {
            // backspace to empty
            textField.text = ""
            hideTextField()
            return true
        } else if text == "\n"  {
            textField.resignFirstResponder()
        } else if (textFieldSize + textSize) > 30 {
            let diff = (textFieldSize - textSize) - 30
            textField.text = (text as NSString).substringToIndex(diff - 1)
        }
        return true
    }

    func setupTextField() {
        // TextView
        textField.translatesAutoresizingMaskIntoConstraints = false
        textField.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.7)
        textField.textColor = UIColor.whiteColor()
        textField.font = UIFont.systemFontOfSize(14.0)
        textField.textAlignment = NSTextAlignment.Center
        textField.text = ""
        textField.hidden = true
        textField.delegate = self
        self.view.addSubview(textField);

        // Text view constraints
        let leftConstraint = textField.leftAnchor.constraintEqualToAnchor(view.leftAnchor)
        let rightConstraint = textField.rightAnchor.constraintEqualToAnchor(view.rightAnchor)
        let heightConstraint = textField.heightAnchor.constraintEqualToConstant(textFieldHeight)
        let verticalConstraint = textField.topAnchor.constraintEqualToAnchor(view.topAnchor, constant: 200)
        NSLayoutConstraint.activateConstraints([leftConstraint, rightConstraint, heightConstraint, verticalConstraint])

        // Tap gesture recognizer; if no text view is visible, shows text view at vertical location of tap
        tapGestureRecognizer.delegate = self
        tapGestureRecognizer.addTarget(self, action: "tapGesture:")
        view.addGestureRecognizer(tapGestureRecognizer)
    }

    func tapGesture(rec:UITapGestureRecognizer) {
        // Show the textView in a location?
        if textField.hidden == false {
            if (textField.text!.characters.count == 0) {
                hideTextField()
            } else {
                restoreTextFieldPosition()
            }
        } else {
            moveTextFieldToEditingPosition()
        }
    }


    func moveTextFieldToEditingPosition() {
        // Textview animates into position a la snapchat
        self.textField.userInteractionEnabled = false
        textField.hidden = false
        UIView.animateWithDuration(0.2, animations: { () -> Void in
            self.textField.center.y = self.textFieldTypingPositionY
            }, completion: { (Bool) -> Void in
                self.textField.userInteractionEnabled = true
                self.textField.becomeFirstResponder()
        })
    }

    func hideTextField() {
        // Hide text view and reset position
        textField.resignFirstResponder()
        textField.userInteractionEnabled = false
        UIView.animateWithDuration(0.2, animations: { () -> Void in
            }, completion: { (Bool) -> Void in
                self.textField.hidden = true
        })
    }



    func restoreTextFieldPosition() {
        // Restore original position of textview after exiting keyboard
        self.textField.userInteractionEnabled = false
        textField.resignFirstResponder()
        UIView.animateWithDuration(0.2, animations: { () -> Void in
            }, completion: { (Bool) -> Void in
                self.textField.userInteractionEnabled = true
        })
    }

}

回答1:

I had this issue with iOS 9. It was ok on iOS 7 and 8. Basically I have a UITextField in a collection view cell. Sometimes when the user is done typing and editing ends, the text "bounces" up then down again into its correct position. Very strange and annoying glitch. Simply making this tweak fixed the issue on iOS 9 and proved to be safe on iOS 7 and 8:

 - (void)textFieldDidEndEditing:(UITextField *)textField
 {
    [textField layoutIfNeeded]; //Fixes iOS 9 text bounce glitch
    //...other stuff
 }


回答2:

this is strange behaviour of textField. I have same issue and the reason is what you are changing the position of textField.

Solution

whatever you have write code for changing position (Y position in your case) using uiview.animation.... Remove this code

And i'm damn sure this bounce will occur when you remove the focus or switch to another control.

Finally, Remove animation code or leave this bounce animation (not bad).

:)



回答3:

Not sure if you solved this, but for me it was because I had a piece of code in my UITextFieldDelegate calling layoutIfNeeded - which was causing all the auto-layout constraints to be recalculated.

I removed the layoutIfNeeded and seemed to have fixed the bouncing