Как выполнить подсчет UITextField в режиме ввода (Swift)?

Я хотел бы пересчитать символ, когда пользователь продолжает печатать в UITextField со скоростью.

Изображение поля и метки:

enter image description here

Я уже разместил UITextField и UILabel, просто не нашел никакой информации о переполнении стека, также если вы можете сделать это в UITextView, я также ценю это.

Ответ 1

Чтобы использовать функцию ниже, вам нужно реализовать UITextFieldDelegate protocol для текстового поля, которое вы хотите считать. Это UITextField каждый раз, когда UITextField текст UITextField:

Объявление вашего класса должно выглядеть примерно так

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 вам нужно будет добавить логику, чтобы знать, кто вызывает эту функцию.

Ответ 2

Очень элегантное и аккуратное решение существует с использованием UITextFieldDelegate. В моем решении используется концепция селекторов. В селекторе вы сообщаете своему компилятору, какую функцию/действие выполнять, когда происходит конкретное событие. В этом случае - ввод текста в текстовое поле. Убедитесь, что вы установили делегат textField в раскадровку.

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

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

Ответ 3

Для нескольких UITextView

enter image description here

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

Ответ 4

Это позволит только ввести ваш текстовый ввод 14 char

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

И Скриншот

enter image description here

Ответ 5

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
}

Ответ 6

Здесь вы можете сделать это в Swift 3/4.

Сначала убедитесь, что у вас есть делегат textField, установленный в viewDidLoad.

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

Дополнительная информация здесь

Ответ 7

Swift 4 для UITextView изменить текстовое событие UITextViewDelegate

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

}

Ответ 8

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
    }