如何在输入时进行实时 UITextField 计数 (Swift)?

How to do a live UITextField count while typing (Swift)?

当用户在 UITextField 和 swift.

中连续输入时,我想计算字符数

字段和标签的图像:

我已经放置了 UITextField 和 UILabel,只是没有找到任何关于 Stack overflow 的信息,如果你能在 UITextView 中做一个,我也很感激。

要使用下面的函数,您需要在要计数的文本字段上实现 UITextFieldDelegate protocol。每次 UITextFields 文本更改时都会调用此函数:

您的 class 声明应如下所示

class ViewController: UIViewController, UITextFieldDelegate

你应该有一个 @IBOutlet 类似于这个

@IBOutlet var txtValue: UITextField

UITextField 的委托设置为 self

override func viewDidLoad() {
    super.viewDidLoad()
    txtValue.delegate = self                
}

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let newLength = count(textField.text.utf16) + count(string.utf16) - range.length

    mylabel.text =  String(newLength) // Set value of the label
    // myCounter = newLength // Optional: Save this value
    // return newLength <= 25 // Optional: Set limits on input. 
    return true
}

请注意,此函数会在所有 UITextField 上调用,因此如果您有多个 UITextField,您将需要添加一个逻辑以了解 一个正在调用此函数。

这将只允许您的文本字段输入 14 个字符

class ViewController: UIViewController,UITextFieldDelegate {

@IBOutlet weak var textfield: UITextField!
@IBOutlet weak var label: UILabel!
override func viewDidLoad() {
    super.viewDidLoad()
    self.label.text = "14"
    self.textfield.delegate = self
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    let newLength = count(textField.text.utf16) + count(string.utf16) - range.length
    if(newLength <= 14){
        self.label.text = "\(14 - newLength)"
        return true
    }else{
        return false
    }
}
}

和截图

In Swift
viewDidLoad {
self.yourTextView.delegate = self
self.updateCharacterCount()
}

func updateCharacterCount() {
    self.yourLabel.text = "\((65) - self.yourTextView.text.characters.count)"  
}

func textViewDidChange(textView: UITextView) {
    self.updateCharacterCount()
}


func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
    self.updateCharacterCount()
    return textView.text.characters.count +  (text.characters.count - range.length) <= 65
}

使用 UITextFieldDelegate 存在一个非常优雅和整洁的解决方案。我的解决方案使用选择器的概念。在选择器中,您告诉编译器当特定事件发生时要执行什么function/action。在这种情况下 - 在文本字段中键入。请确保您已在故事板中设置 textField 委托。

override func viewDidLoad() {
   super.viewDidLoad()
   yourTextField.addTarget(self, action: #selector(YourViewController.textFieldDidChange(_:)), for: UIControlEvents.EditingChanged)
}

@objc func textFieldDidChange(textField : UITextField){
   label.text = yourTextField.text?.count
}

以下是 Swift 3/4 的完成方法。

首先,确保在 viewDidLoad 中设置了 textField 的委托。

yourTextField.delegate = self

然后,执行shouldChangeCharactersIn:

extension YourViewController: UITextFieldDelegate {
    func textField(_ textFieldToChange: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
      // limit to 4 characters
      let characterCountLimit = 4

      // We need to figure out how many characters would be in the string after the change happens
      let startingLength = textFieldToChange.text?.characters.count ?? 0
      let lengthToAdd = string.characters.count
      let lengthToReplace = range.length

      let newLength = startingLength + lengthToAdd - lengthToReplace

      return newLength <= characterCountLimit
    } 
}

其他详细信息here

Swift 4 for UITextView 更改文本事件 UITextViewDelegate

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {

}

多个UITextView

class ViewController: UIViewController, UITextViewDelegate {

 @IBOutlet weak var ticketSummaryTV: UITextView!
 @IBOutlet weak var ticketDescriptionTV: UITextView!

 @IBOutlet weak var summaryCountLbl: UILabel!
 @IBOutlet weak var descriptionCountLbl: UILabel!

 override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.

    ticketSummaryTV.delegate = self
    ticketDescriptionTV.delegate = self

    self.updateCharacterCount()
 }

 func updateCharacterCount() {
    let summaryCount = self.ticketSummaryTV.text.characters.count
    let descriptionCount = self.ticketDescriptionTV.text.characters.count

    self.summaryCountLbl.text = "\((0) + summaryCount)/50"

    self.descriptionCountLbl.text = "\((0) + descriptionCount)/500"
 }

 func textViewDidChange(_ textView: UITextView) {
    self.updateCharacterCount()
 }


 func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool{
    if(textView == ticketSummaryTV){
       return textView.text.characters.count +  (text.characters.count - range.length) <= 50
    }else if(textView == ticketDescriptionTV){
        return textView.text.characters.count +  (text.characters.count - range.length) <= 500
    }
    return false
 }
}

Swift 5.1

添加viewController委托

final class CreditCardViewController : BaseViewController , UITextFieldDelegate {

    @IBOutlet var cvvTextField: UITextField!

添加viewDidLoad()

cvvTextField.delegate = self

并添加委托功能。

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if(textField == cvvTextField){
            let characterCountLimit = 3
            let startingLength = textField.text?.count ?? 0
            let lengthToAdd = string.count
            let lengthToReplace = range.length

            let newLength = startingLength + lengthToAdd - lengthToReplace

            return newLength <= characterCountLimit
        }

        return true
    }

UITextView 计数时输入 Swift:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {

        let textCount = textView.text?.count ?? 0 + text.count - range.length
        self.textCountLabel.text  = "\(textCount)"
        return true
    }

Swift 5.3

添加UITextFieldDelegate在你viewController with outlets

class ViewController: UIViewController, UITextFieldDelegate{
     @IBOutlet weak var txtGroupName: UITextField!
     @IBOutlet weak var lblWordCount: UILabel!

在您的 viewDidLoad() 中添加 textfeild 委托,如下所示

override func viewDidLoad() {
   super.viewDidLoad()
   txtGroupName.addTarget(self, action: #selector(self.textFieldDidChange(textField:)), for: UIControl.Event.editingChanged)
  }
    
   @objc func textFieldDidChange(textField : UITextField){
    self.lblWordCount.text = "\(self.txtGroupName.text!.count)/"+"\(65)"
  }

我们还设置了 最大文本限制 65。你可以将65替换成你想要的

extension viewController:UITextFieldDelegate{
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if !(textField.text?.isEmpty ?? true){
            return textField.text!.count +  (string.count - range.length) <= 65
        }
        return true
    }
}

它的输出如下

简单...

像这样将 UITextViewDelegate 添加到您的 class header...

class ViewController: UIViewController, UITextFieldDelegate { ... }

像这样将 @IBOutlet 添加到 UILabelUITextView...

@IBOutlet weak var characterCountLabel: UILabel!
@IBOutlet var characterTextField: UITextView!

然后将以下委托添加到 viewDidLoad() 函数...

override func viewDidLoad() {
    super.viewDidLoad()
    self.characterTextField.delegate = self // required for character counter
}

最后,只需为 textViewDidChange 委托方法创建一个 func...

func textViewDidChange(_ textView: UITextView) {
    self.characterCountLabel.text = String("\(textView.text.count)")
}

我亲自检查并验证了这种为您的 UITextView 添加文本计数器并将其输出到 UILabel 的简单方法,并且有效!