Как ограничить длину текста для разных UITextField в Swift?

У меня есть проект iOS Xcode 7.3 Swift2, над которым я работаю. Он имеет разные UITextFields, которые ограничены 3 цифрами, а именно только цифрами. Они назначены на UITextFieldDelegate, и это работает хорошо.

Вот где я ограничиваю их:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    guard let text = textField.text else { return true }
    let newLength = text.characters.count + string.characters.count - range.length
    let limitLength = 3
    if newLength > limitLength {
        return false
    }

    let numberOnly = NSCharacterSet.init(charactersInString: "0123456789")
    let stringFromTextField = NSCharacterSet.init(charactersInString: string)
    let strValid = numberOnly.isSupersetOfSet(stringFromTextField)

    return strValid
}

Тем не менее, некоторые из UITextFields должны быть по-прежнему ограничены числами И также должны быть ограничены одной цифрой, как я могу установить это в разделе выше, только для этих конкретных UITextFields?

Имена UITextFields, которые должны быть однозначными:

widthInches
lengthInches

Я попытался разместить это после первой секции охраны, но безуспешно:

guard let text2 = widthInches.text else { return true }
let newLength2 = text2.characters.count + string.characters.count - range.length
let limitLength2 = 3
if newLength2 > limitLength2 {
    return false
}

person ChallengerGuy    schedule 08.06.2016    source источник
comment
все ответы здесь очень устарели, просто сделайте это stackoverflow.com/a/43099816/294884   -  person Fattie    schedule 29.03.2017


Ответы (5)


Функция shouldChangeCharactersInRange передает конкретное текстовое поле в качестве одного из своих параметров. Вы можете посмотреть на это и посмотреть, указывает ли он на тот же экземпляр, что и те, которые вы хотите сократить, например так:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

    guard let text = textField.text else { return true }
    var limitLength = 3
    if textField == widthInches || textField == lengthInches {
      limitLength = 1
    }

    let newLength = text.characters.count + string.characters.count - range.length
    if newLength > limitLength {
      return false
    }

    let numberOnly = NSCharacterSet.init(charactersInString: "0123456789")
    let stringFromTextField = NSCharacterSet.init(charactersInString: string)
    let strValid = numberOnly.isSupersetOfSet(stringFromTextField)

    return strValid
  }

Предполагая, что все остальные требования одинаковы (только цифры), это поможет.

Есть и другие способы, например: вы можете подклассировать UITextField и добавить поле limitLength, а затем использовать это поле в делегате, но это, вероятно, излишне для всего 2 исключений.

person DJohnson    schedule 08.06.2016
comment
Спасибо. Я не думаю, что делать подкласс необходимо. Другой способ имеет смысл. - person ChallengerGuy; 09.06.2016
comment
В итоге мне понадобилось больше текстовых полей, чем я изначально думал, что нужно ограничение в 1. Я пошел с тем, что вы сказали, но вместо оператора if..then пошел с оператором case для нескольких UITextFields. Работает отлично! - person ChallengerGuy; 09.06.2016

Вы также можете попробовать этот код для ограничения текстового поля

на самом деле я использую здесь тег текстового поля. Потому что пользовательское текстовое поле. Если вы используете собственное текстовое поле, такое как TextfieldEffect, в этом теге условия поможет вам ограничить текстовое поле.

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool{
        
        if textField.tag == txtCountryCode.tag{
            let maxLength = 4
            let currentString: NSString = textField.text!
            let newString: NSString =
            currentString.stringByReplacingCharactersInRange(range, withString: string)
            return newString.length <= maxLength
        }

        
        if textField.tag == txtMobileNumber.tag{
            let maxLength = 10
            let currentString: NSString = textField.text!
            let newString: NSString =
            currentString.stringByReplacingCharactersInRange(range, withString: string)
            return newString.length <= maxLength
        }
        
        return true
    }

Я надеюсь, что это поможет вам.

person Anand Nimje    schedule 10.06.2016
comment
Я не знал, что вы можете добавлять теги в UITextFields, не говоря уже об использовании их в UITextFieldDelegate. Мне придется изучить это в будущем. Спасибо. - person ChallengerGuy; 10.06.2016
comment
На самом деле, почему я использовал это, потому что я не использую UITextfield, я использую пользовательское текстовое поле, поэтому я столкнулся с проблемой, тогда я получил решение для этого с использованием тега. - person Anand Nimje; 11.06.2016

Здравствуйте, в вашем func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool параметр textField - это текстовое поле, которое вызывает это событие, поэтому вы можете проверить свои объекты текстовых полей, и если они равны одному из них, то сделайте другое поведение

Я надеюсь, это поможет вам,

person Reinier Melian    schedule 08.06.2016

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {  
    return (textField.text?.utf16.count ?? 0) + string.utf16.count - range.length <= TEXT_FIELD_LIMIT
}

Это подсчитывает количество символов на основе представления UTF-16, так как range.length задается в базе UTF-16. Если вам нужно подсчитать количество символов другими способами, выражение может стать длиннее. Если вы хотите, чтобы вводились только числа, используйте textField.keyboardType = UIKeyboardTypeDecimalPad . Если вам нужны определенные текстовые поля, добавьте теги и сравните их, и если они равны, вы можете реализовать для этого свой конкретный код.

Проверьте эту ссылку для получения подробного ответа: длины и принятия или отклонения конкретных символов/" rel="nofollow">http://www.globalnerdy.com/2016/05/24/a-better-way-to-program-ios-text -поля-максимальной-длины-и-принятия-или-отклонения-специфических-символов/

person Sushree Swagatika    schedule 08.06.2016
comment
Это не имеет никакого отношения к вопросу. - person rmaddy; 08.06.2016
comment
Я понимаю тип клавиатуры, однако на iPad он также имеет такие символы, как $, & и т. д., что было причиной указания фактических чисел для использования в моем коде. iPhone не имел большого значения. - person ChallengerGuy; 08.06.2016

update для swift 3 добавьте этот класс и назовите его TextField.swift. это добавит ограничение ввода на раскадровке.

  import UIKit 
  private var maxLengths = [UITextField: Int]()

   extension UITextField {

 @IBInspectable var maxLength: Int {
  get {
     guard let length = maxLengths[self] else {
       return Int.max
   }
   return length
 }
  set {
    maxLengths[self] = newValue
    // Any text field with a set max length will call the limitLength
    // method any time it's edited (i.e. when the user adds, removes,
    // cuts, or pastes characters to/from the text field).
      addTarget(
          self,
          action: #selector(limitLength),
          for: UIControlEvents.editingChanged
      )
  }
 }

   func limitLength(textField: UITextField) {
     guard let prospectiveText = textField.text, 
      prospectiveText.characters.count > maxLength else {
     return
   }

      // If the change in the text field's contents will exceed its maximum 
     length,
     // allow only the first [maxLength] characters of the resulting text.
     let selection = selectedTextRange

    // text = prospectiveText.substring(with:Range<String.Index>
    (prospectiveText.startIndex ..< prospectiveText.index(after: maxLength))
    let s = prospectiveText

      // Get range 4 places from the start, and 6 from the end.
     let c = s.characters;

      let r = c.index(c.startIndex, offsetBy: 0)..<c.index(c.endIndex, offsetBy:   maxLength - c.count)
       text = s[r]


     // Access the string by the range.


     selectedTextRange = selection
    }

   }

или скачать здесь - ›TextField.swift

person juzt    schedule 10.08.2017