PlaceHolder 在 iOS 中开始在 TextField 中输入时动画

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35035443/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 08:21:31  来源:igfitidea点击:

PlaceHolder animates when start typing in TextField in iOS

iosobjective-cswiftuitextfieldplaceholder

提问by Meet Doshi

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

如何设置这种类型的动画UITextField?如今,许多应用程序都在使用它。

enter image description here

在此处输入图片说明

采纳答案by Meet Doshi

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

我找到了解决方案。您可以使用多个标签管理此类动画,并将这些标签显示-隐藏到textFieldDidBeginEditing方法中。

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

如果您想要与您在问题中描述的相同的漂亮动画,请尝试关注UITextField.

If you are looking for the UITextViewequivalent of this animation, please visit UIFloatLabelTextViewrepository.

如果您正在寻找UITextView与此动画等效的内容,请访问UIFloatLabelTextView存储库。

回答by Rouny

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、Img2 和 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).

Img1 指向故事板,我们在那里设计了我们的界面。这里我们使用了三个标签,每个标签后跟 TextField 和 UIView(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.

Img2:它指向应用启动时的初始屏幕,或者当我们按下底部的“注册”按钮时,它会重置屏幕。在此图像中,标签被隐藏,因为文本字段为空白且视图颜色为灰色。

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.

Img3:此图像反映了对 Textfield 的编辑。当我们开始编辑文本字段(这里是第一个,即名称)时,标签出现,文本字段的大小减小,占位符更改并且视图颜色更改为黑色。

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 = "[email protected]"
        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)   
  }
}

Img1 : StoryBoard

Img1 : 故事板

Img2: Initial ScreenImg3: Textfield Editing

img2:初始屏幕img3:文本字段编辑

回答by Jamil Hasnine Tamim

For Swift 4.0 and 4.2

对于Swift 4.0 和 4.2

Check this library for floating textField

检查此库以获取浮动 textField

https://github.com/hasnine/iOSUtilitiesSource

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

回答by emrcftci

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

您可以使用 SkyFloatingLabelTextField。它是 SkyScanner 用于此类标签或文本字段动画的库。

https://github.com/Skyscanner/SkyFloatingLabelTextField

https://github.com/Skyscanner/SkyFloatingLabelTextField

I hope this answer will works for you.

我希望这个答案对你有用。

Enjoy.

享受。

回答by Jitendra Singh

You can try using JSInputFieldwhich supports data validations as well.

您可以尝试使用也支持数据验证的JSInputField

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.

回答by Abhinandan Pratap

use this code

使用此代码

[your_textfieldname setShowsTouchWhenHighlighted:YES];