PlaceHolder animates when start typing in TextField in iOS

前端 未结 6 1262
忘了有多久
忘了有多久 2021-01-31 05:22

How to set this type of animation in UITextField? Nowadays, Many apps are using this.

相关标签:
6条回答
  • 2021-01-31 05:35

    For Swift 4.0 and 4.2

    Check this library for floating textField

    https://github.com/hasnine/iOSUtilitiesSource

    Code:

    enum placeholderDirection: String {
        case placeholderUp = "up"
        case placeholderDown = "down"
    
    }
    public class IuFloatingTextFiledPlaceHolder: UITextField {
        var enableMaterialPlaceHolder : Bool = true
        var placeholderAttributes = NSDictionary()
        var lblPlaceHolder = UILabel()
        var defaultFont = UIFont()
        var difference: CGFloat = 22.0
        var directionMaterial = placeholderDirection.placeholderUp
        var isUnderLineAvailabe : Bool = true
        override init(frame: CGRect) {
            super.init(frame: frame)
            Initialize ()
        }
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            Initialize ()
        }
        func Initialize(){
            self.clipsToBounds = false
            self.addTarget(self, action: #selector(IuFloatingTextFiledPlaceHolder.textFieldDidChange), for: .editingChanged)
            self.EnableMaterialPlaceHolder(enableMaterialPlaceHolder: true)
            if isUnderLineAvailabe {
                let underLine = UIImageView()
                underLine.backgroundColor = UIColor.init(red: 197/255.0, green: 197/255.0, blue: 197/255.0, alpha: 0.8)
                //            underLine.frame = CGRectMake(0, self.frame.size.height-1, self.frame.size.width, 1)
                underLine.frame = CGRect(x: 0, y: self.frame.size.height-1, width : self.frame.size.width, height : 1)
    
                underLine.clipsToBounds = true
                self.addSubview(underLine)
            }
            defaultFont = self.font!
    
        }
        @IBInspectable var placeHolderColor: UIColor? = UIColor.lightGray {
            didSet {
                self.attributedPlaceholder = NSAttributedString(string: self.placeholder! as String ,
                                                                attributes:[NSAttributedString.Key.foregroundColor: placeHolderColor!])
            }
        }
        override public var placeholder:String?  {
            didSet {
                //  NSLog("placeholder = \(placeholder)")
            }
            willSet {
                let atts  = [NSAttributedString.Key.foregroundColor.rawValue: UIColor.lightGray, NSAttributedString.Key.font: UIFont.labelFontSize] as! [NSAttributedString.Key : Any]
                self.attributedPlaceholder = NSAttributedString(string: newValue!, attributes:atts)
                self.EnableMaterialPlaceHolder(enableMaterialPlaceHolder: self.enableMaterialPlaceHolder)
            }
    
        }
        override public var attributedText:NSAttributedString?  {
            didSet {
                //  NSLog("text = \(text)")
            }
            willSet {
                if (self.placeholder != nil) && (self.text != "")
                {
                    let string = NSString(string : self.placeholder!)
                    self.placeholderText(string)
                }
    
            }
        }
        @objc func textFieldDidChange(){
            if self.enableMaterialPlaceHolder {
                if (self.text == nil) || (self.text?.count)! > 0 {
                    self.lblPlaceHolder.alpha = 1
                    self.attributedPlaceholder = nil
                    self.lblPlaceHolder.textColor = self.placeHolderColor
                    self.lblPlaceHolder.frame.origin.x = 0 ////\\
                    let fontSize = self.font!.pointSize;
                    self.lblPlaceHolder.font = UIFont.init(name: (self.font?.fontName)!, size: fontSize-3)
                }
                UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 1, options: .curveEaseInOut, animations: {() -> Void in
                    if (self.text == nil) || (self.text?.count)! <= 0 {
                        self.lblPlaceHolder.font = self.defaultFont
                        self.lblPlaceHolder.frame = CGRect(x: self.lblPlaceHolder.frame.origin.x+10, y : 0, width :self.frame.size.width, height : self.frame.size.height)
                    }
                    else {
                        if self.directionMaterial == placeholderDirection.placeholderUp {
                            self.lblPlaceHolder.frame = CGRect(x : self.lblPlaceHolder.frame.origin.x, y : -self.difference, width : self.frame.size.width, height : self.frame.size.height)
                        }else{
                            self.lblPlaceHolder.frame = CGRect(x : self.lblPlaceHolder.frame.origin.x, y : self.difference, width : self.frame.size.width, height : self.frame.size.height)
                        }
    
                    }
                }, completion: {(finished: Bool) -> Void in
                })
            }
        }
        func EnableMaterialPlaceHolder(enableMaterialPlaceHolder: Bool){
            self.enableMaterialPlaceHolder = enableMaterialPlaceHolder
            self.lblPlaceHolder = UILabel()
            self.lblPlaceHolder.frame = CGRect(x: 0, y : 0, width : 0, height :self.frame.size.height)
            self.lblPlaceHolder.font = UIFont.systemFont(ofSize: 10)
            self.lblPlaceHolder.alpha = 0
            self.lblPlaceHolder.clipsToBounds = true
            self.addSubview(self.lblPlaceHolder)
            self.lblPlaceHolder.attributedText = self.attributedPlaceholder
            //self.lblPlaceHolder.sizeToFit()
        }
        func placeholderText(_ placeholder: NSString){
            let atts  = [NSAttributedString.Key.foregroundColor: UIColor.lightGray, NSAttributedString.Key.font: UIFont.labelFontSize] as [NSAttributedString.Key : Any]
            self.attributedPlaceholder = NSAttributedString(string: placeholder as String , attributes:atts)
            self.EnableMaterialPlaceHolder(enableMaterialPlaceHolder: self.enableMaterialPlaceHolder)
        }
        override public func becomeFirstResponder()->(Bool){
            let returnValue = super.becomeFirstResponder()
            return returnValue
        }
        override public func resignFirstResponder()->(Bool){
            let returnValue = super.resignFirstResponder()
            return returnValue
        }
    
        override public func layoutSubviews() {
            super.layoutSubviews()
        }
    }
    

    0 讨论(0)
  • 2021-01-31 05:39

    I've found the solution. You can manage this type of animation using multiple labels, and show-hide those labels into textFieldDidBeginEditing method.

    If you want nice animation same as you describe into your question, then try once following third party repository for UITextField.

    • JVFloatLabeledTextField
    • UIFloatLabelTextField
    • FloatLabelFields

    If you are looking for the UITextView equivalent of this animation, please visit UIFloatLabelTextView repository.

    0 讨论(0)
  • 2021-01-31 05:45

    You can try using JSInputField which supports data validations as well.

    JSInputField *inputField = [[JSInputField alloc] initWithFrame:CGRectMake(10, 100, 300, 50)];
    [self.view addSubview:inputField];
    [inputField setPlaceholder:@"Enter Text"];
    [inputField setRoundedCorners:UIRectCornerAllCorners];
    [inputField addValidationRule:JSCreateRuleNotNullValue]; //This will validate field for null value. It will show error if field is empty.
    [inputField addValidationRule:JSCreateRuleNumeric(2)];  //This will validate field for numeric values and restrict to enter value upto 2 decimal places.
    
    0 讨论(0)
  • 2021-01-31 05:47

    This problem can be solved logically with the use of multiple labels and text-fields and later we can add animation if needed. I will like to explain this problem using three images, namely Img1, Img2 and Img3.

    Img1 points to storyboard, where we have designed our interface. Here we have used three Labels each followed by TextField and UIView(line below Textfield).

    Img2: It points to the initial screen when the app launches or when we press the "Sign up" Button at the bottom, which resets the screen. In this Image, the labels are hidden as textfields are blank with and view color is gray.

    Img3: This image reflects the editing of Textfield. As we start editing text field(here the first one, namely name), the label shows up, size of textfield decreases, placeholder changes and color of view changes to black.

    We need to keep one more thing in mind, when we stop editing any textfield and if it is still blank then set it properties to original.

    I am adding code for this Question which I was asked as assignment in an interview.

    import UIKit
    
    class FloatingLabelViewController: UIViewController, UITextFieldDelegate, UINavigationControllerDelegate {
    
    
      //UITextFieldDelegate - protocol defines methods that you use to manage the editing and validation of text in a UITextField object. All of the methods of this protocol are optional.
    
      //UINavigationControllerDelegate - Use a navigation controller delegate (a custom object that implements this protocol) to modify behavior when a view controller is pushed or popped from the navigation stack of a UINavigationController object.
    
      @IBOutlet weak var NameLbl: UILabel!
      @IBOutlet weak var EmailLbl: UILabel!
      @IBOutlet weak var PasswordLbl: UILabel!
    
      @IBOutlet weak var NameTxf: UITextField!
      @IBOutlet weak var EmailTxf: UITextField!
      @IBOutlet weak var PasswordTxf: UITextField!
    
      @IBOutlet weak var SignUpBtn: UIButton!
    
      @IBOutlet weak var NameView: UIView!
      @IBOutlet weak var EmailView: UIView!
      @IBOutlet weak var PasswordView: UIView!
    
    
      override func viewDidLoad() {
        super.viewDidLoad()
    
    
        NameTxf.delegate = self
        EmailTxf.delegate = self
        PasswordTxf.delegate = self
    
        self.property()
    
        //black  is varaiable here
        //setTitleColor - Sets the color of the title to use for the specified state
        //var layer - The view’s Core Animation layer used for rendering. this propert is never nil
        //cg color - Quartz color refernce
    
        SignUpBtn.backgroundColor = UIColor.black
        SignUpBtn.setTitleColor(UIColor.white, for: .normal)
        SignUpBtn.layer.borderWidth = 1
        SignUpBtn.layer.borderColor = UIColor.black.cgColor
    
        //Tap guesture recognizer to hide keyboard
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(FloatingLabelViewController.dismissKeyboard))
        view.addGestureRecognizer(tap)
    
        // UITapGestureRecognizer - UITapGestureRecognizer is a concrete subclass of UIGestureRecognizer that looks for single or multiple taps. For the gesture to be recognized, the specified number of fingers must tap the view a specified number of times.
    
    
      }
    
      override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    
      }
    
      //textFieldShouldReturn - Asks the delegate if the text field should process the pressing of the return button. The text field calls this method whenever the user taps the return button.  YES if the text field should implement its default behavior for the return button; otherwise, NO.
    
      // endEditing - Causes the view (or one of its embedded text fields) to resign the first responder status.
    
      func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        self.view.endEditing(true)
        return false
      }
    
    
      func dismissKeyboard() {
        //Causes the view (or one of its embedded text fields) to resign the first responder status.
        view.endEditing(true)
      }
    
      //When user Starts Editing the textfield
      // textFieldDidBeginEditing - Tells the delegate that editing began in the specified text field
    
      func textFieldDidBeginEditing(_ textField: UITextField) {
    
        if textField == self.NameTxf
        {
    
            self.NameTxf.font = UIFont.italicSystemFont(ofSize: 15)
            self.NameLbl.isHidden = false
            self.NameLbl.text = self.NameTxf.placeholder
            self.NameTxf.placeholder = "First Last"
            NameView.backgroundColor = UIColor.black.withAlphaComponent(0.5)
    
    
        }
    
        else if textField == self.EmailTxf
        {
            self.EmailTxf.font = UIFont.italicSystemFont(ofSize: 15)
            self.EmailLbl.isHidden = false
            self.EmailLbl.text = self.EmailTxf.placeholder
            self.EmailTxf.placeholder = "abc@gmail.com"
            EmailView.backgroundColor = UIColor.black.withAlphaComponent(0.5)
    
    
        }
    
        else if textField == self.PasswordTxf
        {
            self.PasswordTxf.font = UIFont.italicSystemFont(ofSize: 15)
            self.PasswordLbl.isHidden = false
            self.PasswordLbl.text = self.PasswordTxf.placeholder
            self.PasswordTxf.placeholder = "........."
            PasswordView.backgroundColor = UIColor.black.withAlphaComponent(0.5)
    
    
        }
    
    
      }
    
    
      //When User End editing the textfield.
    
      // textFieldDidEndEditing - Tells the delegate that editing stopped for the specified text field.
    
      func textFieldDidEndEditing(_ textField: UITextField) {
    
    
        //Checkes if textfield is empty or not after after user ends editing.
        if textField == self.NameTxf
        {
            if self.NameTxf.text == ""
            {
            self.NameTxf.font = UIFont.italicSystemFont(ofSize: 25)
            self.NameLbl.isHidden = true
            self.NameTxf.placeholder = "Name"
            NameView.backgroundColor = UIColor.lightGray.withAlphaComponent(0.5)
    
    
    
    
        }
    
    
        }
    
    
        else if textField == self.EmailTxf
        {
            if self.EmailTxf.text == ""
            {
                self.EmailTxf.font = UIFont.italicSystemFont(ofSize: 25)
                self.EmailLbl.isHidden = true
                self.EmailTxf.placeholder = "Email"
                EmailView.backgroundColor = UIColor.lightGray.withAlphaComponent(0.5)
    
    
    
            }
    
    
        }
    
    
    
        else if textField == self.PasswordTxf
        {
            if self.PasswordTxf.text == ""
            {
                self.PasswordTxf.font = UIFont.italicSystemFont(ofSize: 25)
                self.PasswordLbl.isHidden = true
                self.PasswordTxf.placeholder = "Password"
                PasswordView.backgroundColor = UIColor.lightGray.withAlphaComponent(0.5)
    
    
            }
    
    
        }
    
    
      }
    
      //Action on SingUp button Clicked.
      @IBAction func signupClicked(_ sender: Any) {
    
          self.property()
          self.dismissKeyboard() //TO dismiss the Keyboard on the click of SIGNUP button.
    
      }
    
    
      //Function to set the property of Textfields, Views corresponding to TextFields and Labels.
      func property(){
    
        NameLbl.isHidden =  true
        EmailLbl.isHidden = true
        PasswordLbl.isHidden = true
    
        NameTxf.text = ""
        EmailTxf.text = ""
        PasswordTxf.text = ""
    
        NameTxf.placeholder = "Name"
        EmailTxf.placeholder = "Email"
        PasswordTxf.placeholder = "Password"
    
    
        self.NameTxf.font = UIFont.italicSystemFont(ofSize: 25)
        self.EmailTxf.font = UIFont.italicSystemFont(ofSize: 25)
        self.PasswordTxf.font = UIFont.italicSystemFont(ofSize: 25)
    
        EmailTxf.keyboardType = UIKeyboardType.emailAddress
        PasswordTxf.isSecureTextEntry = true
        NameTxf.autocorrectionType = .no
        EmailTxf.autocorrectionType = .no
    
        NameView.backgroundColor = UIColor.lightGray.withAlphaComponent(0.5)
        EmailView.backgroundColor = UIColor.lightGray.withAlphaComponent(0.5)
        PasswordView.backgroundColor = UIColor.lightGray.withAlphaComponent(0.5)   
      }
    }
    

    0 讨论(0)
  • 2021-01-31 05:53

    use this code

    [your_textfieldname setShowsTouchWhenHighlighted:YES];
    
    0 讨论(0)
  • 2021-01-31 05:57

    You can use SkyFloatingLabelTextField. It is SkyScanner's library for this kind of label or textField animations.

    https://github.com/Skyscanner/SkyFloatingLabelTextField

    I hope this answer will works for you.

    Enjoy.

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