web-dev-qa-db-ja.com

iOSでTextFieldに入力を開始すると、PlaceHolderがアニメーション化します

UITextFieldでこのタイプのアニメーションを設定する方法は?現在、多くのアプリがこれを使用しています。

enter image description here

18
Meet Doshi

私は解決策を見つけました。複数のラベルを使用してこのタイプのアニメーションを管理し、それらのラベルをtextFieldDidBeginEditingメソッドで非表示にできます。

質問で説明したのと同じニースアニメーションが必要な場合は、UITextFieldのサードパーティのリポジトリに従ってください。

このアニメーションに相当するUITextViewを探している場合は、 IFloatLabelTextView repositoryにアクセスしてください。

17
Meet Doshi

この問題は、複数のラベルとテキストフィールドを使用することで論理的に解決でき、必要に応じて後でアニメーションを追加できます。 Img1、Img2、Img3の3つの画像を使用してこの問題を説明します。

Img1は、インターフェイスを設計したストーリーボードを指します。ここでは、3つのラベルを使用し、それぞれにTextFieldとUIView(Textfieldの下の行)を続けています。

Img2:アプリが起動したとき、または画面をリセットする下部の「サインアップ」ボタンを押したときの初期画面を指します。この画像では、テキストフィールドが空白で表示色が灰色であるため、ラベルは非表示になっています。

Img3:この画像は、テキストフィールドの編集を反映しています。テキストフィールド(ここでは最初のフィールド、つまり名前)の編集を開始すると、ラベルが表示され、テキストフィールドのサイズが小さくなり、プレースホルダーが変わり、ビューの色が黒に変わります。

テキストフィールドの編集を停止し、まだ空白の場合は、プロパティを元に設定するときに、もう1つ注意する必要があります。

インタビューで課題として尋ねられたこの質問のコードを追加しています。

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

Img2: Initial ScreenImg3: Textfield Editing

4
Rouny

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.
2
Jitendra Singh

Swift 4.0および4.2

このライブラリでフローティングtextFieldを確認してください

https://github.com/hasnine/iOSUtilitiesSource

コード:

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

2

SkyFloatingLabelTextFieldを使用できます。この種のラベルまたはtextFieldアニメーション用のSkyScannerのライブラリです。

https://github.com/Skyscanner/SkyFloatingLabelTextField

この回答があなたに役立つことを願っています。

楽しい。

1
Emre Ciftci

このコードを使用

[your_textfieldname setShowsTouchWhenHighlighted:YES];
0