it-swarm.com.de

Legen Sie die maximale Zeichenlänge eines UITextFields in Swift fest

Ich weiß, dass es andere Themen zu diesem Thema gibt, aber ich scheine nicht herauszufinden, wie ich es umsetzen kann. 

Ich versuche, ein UITextField auf nur 5 Zeichen zu beschränken 

Vorzugsweise alphanumerisch und - und. und _ 

Ich habe diesen Code gesehen 

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

und 

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

    let length = count(textField.text.utf16) + count(string.utf16) - range.length
    return length <= 10 
}

Ich weiß einfach nicht, wie ich es implementieren soll oder welches "Textfeld" ich für meinen benutzerdefinierten Namen UITextField eintauschen sollte

43
ishkur88
  1. Ihr View-Controller sollte wie folgt der UITextFieldDelegate entsprechen:

    class MyViewController: UIViewController, UITextFieldDelegate {
    
    }
    
  2. Legen Sie den Delegierten Ihres Textfelds fest: myTextField.delegate = self

  3. Implementieren Sie die Methode in Ihrem View Controller: textField(_:shouldChangeCharactersInRange:replacementString:)

Alle zusammen:

class MyViewController: UIViewController,UITextFieldDelegate  //set delegate to class 

@IBOutlet var mytextField: UITextField             //  textfield variable 

override func viewDidLoad() {
    super.viewDidLoad()
    mytextField.delegate = self                  //set delegate
}


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

Für Swift 4

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let maxLength = 1
    let currentString: NSString = textField.text! as NSString
    let newString: NSString =
        currentString.replacingCharacters(in: range, with: string) as NSString
    return newString.length <= maxLength
}

Erlauben, dass nur eine bestimmte Gruppe von Zeichen in ein bestimmtes Textfeld eingegeben werden kann

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

  if mytextField == numberField {
    if count(string) > 0 {
      let disallowedCharacterSet = NSCharacterSet(charactersInString: "0123456789.-").invertedSet
      let replacementStringIsLegal = string.rangeOfCharacterFromSet(disallowedCharacterSet) == nil
      result = replacementStringIsLegal
    }
  }

  return result
}

So programmieren Sie ein iOS-Textfeld, das nur numerische Eingaben mit einer maximalen Länge enthält

69
Aladin

Dezember 2017. Schnell 4.

Achten Sie darauf, dass ein Großteil des Beispielcodes, den Sie online in Bezug auf dieses Problem sehen, ist sehr veraltet.

Fügen Sie einfach das Folgende in eine beliebige Swift-Datei in Ihrem Projekt ein. Benennen Sie die Datei irgendetwas, zum Beispiel "Handy.Swift".

Damit ist eines der dümmsten Probleme in iOS behoben:

 enter image description here

Ihre Textfelder haben jetzt einen .maxLength.

Es ist vollkommen in Ordnung, diesen Wert während der Entwicklung im Storyboard oder im Code festzulegen, während die App ausgeführt wird.

// simply have this in any Swift file, say, Handy.Swift

import UIKit
private var __maxLengths = [UITextField: Int]()
extension UITextField {
    @IBInspectable var maxLength: Int {
        get {
            guard let l = __maxLengths[self] else {
               return 150 // (global default-limit. or just, Int.max)
            }
            return l
        }
        set {
            __maxLengths[self] = newValue
            addTarget(self, action: #selector(fix), for: .editingChanged)
        }
    }
    func fix(textField: UITextField) {
        let t = textField.text
        textField.text = t?.safelyLimitedTo(length: maxLength)
    }
}

extension String
    {
    func safelyLimitedTo(length n: Int)->String {
        if (self.count <= n) {
            return self
        }
        return String( Array(self).prefix(upTo: n) )
    }
}

So einfach ist das.


(Hinweis: "safeLimitedTo # length" ist nur ein Aufruf, der die Länge eines Strings abschneidet. Alle Swift-Programmierer haben eine eigene Erweiterung dafür oder verwenden einfach meine, die Sie dort sehen.)


Eine noch einfachere Einzelversion ...

Die obigen Korrekturen all Textfelder in Ihrem Projekt.

Wenn Sie möchten, dass ein bestimmtes Textfeld einfach auf "4" beschränkt ist, und das ist das ...

class PinCodeEntry: UITextField {

    override func didMoveToSuperview() {

        super.didMoveToSuperview()
        addTarget(self, action: #selector(fixMe), for: .editingChanged)
    }

    @objc private func fixMe() { text = text?.safelyLimitedTo(length 4) }
}

Puh! Das ist alles dazu.

(Übrigens, hier ist ein ähnlicher, sehr nützlicher Tipp zu UITextView, https://stackoverflow.com/a/42333832/294884 )

84
Fattie

Swift 4, benutze einfach:

public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    return range.location < 10
}

Genauso wie Steven Schmatz es tat, aber mit Swift 3.0:

//max Length
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,
               replacementString string: String) -> Bool
{
    let maxLength = 4
    let currentString: NSString = textField.text! as NSString
    let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString
    return newString.length <= maxLength
}
7
Pavlos

Ich denke, die Erweiterung ist dafür praktischer. Vollständige Antwort anzeigen hier

private var maxLengths = [UITextField: Int]()

// 2
extension UITextField {

  // 3
  @IBInspectable var maxLength: Int {
    get {
      // 4
      guard let length = maxLengths[self] else {
        return Int.max
      }
      return length
    }
    set {
      maxLengths[self] = newValue
      // 5
      addTarget(
        self,
        action: #selector(limitLength),
        forControlEvents: UIControlEvents.EditingChanged
      )
    }
  }

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

    let selection = selectedTextRange
    // 7
    text = prospectiveText.substringWithRange(
      Range<String.Index>(prospectiveText.startIndex ..< prospectiveText.startIndex.advancedBy(maxLength))
    )
    selectedTextRange = selection
  }

}
6
ZaEeM ZaFaR

Bei anderen oben aufgeführten Lösungen wird aufgrund der Textfeldkarte ein Aufbewahrungszyklus erstellt. Außerdem sollte die maxLength-Eigenschaft nullfähig sein, wenn sie nicht anstelle von künstlichen Int.max-Konstruktionen festgelegt wird. und das Ziel wird mehrmals festgelegt, wenn maxLength geändert wird. 

Hier eine aktualisierte Lösung für Swift4 mit einer schwachen Karte, um Speicherverluste und andere Korrekturen zu verhindern

private var maxLengths = NSMapTable<UITextField, NSNumber>(keyOptions: NSPointerFunctions.Options.weakMemory, valueOptions: NSPointerFunctions.Options.strongMemory)

extension UITextField {

    var maxLength: Int? {
        get {
            return maxLengths.object(forKey: self)?.intValue
        }
        set {
            removeTarget(self, action: #selector(limitLength), for: .editingChanged)
            if let newValue = newValue {
                maxLengths.setObject(NSNumber(value: newValue), forKey: self)
                addTarget(self, action: #selector(limitLength), for: .editingChanged)
            } else {
                maxLengths.removeObject(forKey: self)
            }
        }
    }

    @IBInspectable var maxLengthInspectable: Int {
        get {
            return maxLength ?? Int.max
        }
        set {
            maxLength = newValue
        }
    }

    @objc private func limitLength(_ textField: UITextField) {
        guard let maxLength = maxLength, let prospectiveText = textField.text, prospectiveText.count > maxLength else {
            return
        }
        let selection = selectedTextRange
        text = String(prospectiveText[..<prospectiveText.index(from: maxLength)])
        selectedTextRange = selection
    }
}
4

Meine Swift 4-Version von shouldChangeCharactersIn

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

        guard let preText = textField.text as NSString?,
            preText.replacingCharacters(in: range, with: string).count <= MAX_TEXT_LENGTH else {
            return false
        }

        return true
    }
2
aviran

Diese Antwort ist für Swift 4 und ist ziemlich einfach mit der Möglichkeit, die Rücktaste durchzulassen.

func textField(_ textField: UITextField, 
               shouldChangeCharactersIn range: NSRange, 
               replacementString string: String) -> Bool {
    return textField.text!.count < 10 || string == ""
}
2
CodeBender

Ich habe Aladins Antwort etwas hinzuzufügen:

  1. Ihr View Controller sollte UITextFieldDelegate entsprechen.

    class MyViewController: UIViewController, UITextViewDelegate {
    
    }
    
  2. Legen Sie den Delegaten Ihres Textfelds fest: Um den Delegierten festzulegen, können Sie das Ziehen aus dem Textfeld auf Ihren Ansichtscontroller im Storyboard steuern. Ich denke, das ist vorzuziehen, es im Code zu setzen

  3. Implementieren Sie die Methode in Ihrem View Controller: textField(_:shouldChangeCharactersInRange:replacementString:)

2
SwiftMatt

Ich gebe eine ergänzende Antwort auf der Basis von @Frouo. Ich denke, seine Antwort ist der schönste Weg. Weil es eine gemeinsame Kontrolle ist, die wir wiederverwenden können. Und hier gibt es kein Leckproblem.

    private var kAssociationKeyMaxLength: Int = 0

    extension UITextField {

        @IBInspectable var maxLength: Int {
            get {
                if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLength) as? Int {
                    return length
                } else {
                    return Int.max
                }
            }
            set {
                objc_setAssociatedObject(self, &kAssociationKeyMaxLength, newValue, .OBJC_ASSOCIATION_RETAIN)
                self.addTarget(self, action: #selector(checkMaxLength), for: .editingChanged)
            }
        }

//The method is used to cancel the check when use Chinese Pinyin input method.
        //Becuase the alphabet also appears in the textfield when inputting, we should cancel the check.
        func isInputMethod() -> Bool {
            if let positionRange = self.markedTextRange {
                if let _ = self.position(from: positionRange.start, offset: 0) {
                    return true
                }
            }
            return false
        }


        func checkMaxLength(textField: UITextField) {

            guard !self.isInputMethod(), let prospectiveText = self.text,
                prospectiveText.count > maxLength
                else {
                    return
            }

            let selection = selectedTextRange
            let maxCharIndex = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
            text = prospectiveText.substring(to: maxCharIndex)
            selectedTextRange = selection
        }



    }
2
Victor Choy

update für diese Fattie Antwort

import UIKit

extension UITextField {

    /// Runtime 键
    private struct AssociatedKeys {

        static var maxlength: UInt8 = 0
        static var lastString: UInt8 = 0
    }

    /// 最大输入长度
    @IBInspectable var maxLength: Int {
        get {
            return objc_getAssociatedObject(self, &AssociatedKeys.maxlength) as? Int ?? 0
        }
        set(newValue) {
            objc_setAssociatedObject(self, &AssociatedKeys.maxlength, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            addTarget(self, action: #selector(fix), for: .editingChanged)
        }
    }

    /// 最后一个符合条件的规则
    private var lastQualifiedString: String? {
        get {
            return objc_getAssociatedObject(self, &AssociatedKeys.lastString) as? String
        }
        set(newValue) {
            objc_setAssociatedObject(self, &AssociatedKeys.lastString, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

    @objc func fix(textField: UITextField) {

        guard markedTextRange == nil else { return }

        /// 如果 个数 为最大个数
        /// 在字典中,保存 最大数据
        if textField.text?.count == maxLength {

            /// 在 字典中保存 该数值
            lastQualifiedString = textField.text

            // 在 小于个数时 清除 数据
        } else if textField.text?.count ?? 0 < maxLength {
            lastQualifiedString = nil
        }

        let editRange: UITextRange?

        /// 如果 输入框内的个数大于 最大值
        if textField.text?.count ?? 0 > maxLength {

            /// 将选中的 range 向前移动一个位置
            let position = textField.position(from: safeTextPosition(selectedTextRange?.start), offset: -1) ?? textField.beginningOfDocument

            editRange = textField.textRange(from: safeTextPosition(position), to: safeTextPosition(position))
        } else {

            editRange = selectedTextRange
        }

        /// 配置 值
        textField.text = textField.text?.safelyLimitedTo(length: maxLength, safeText: lastQualifiedString)

        textField.selectedTextRange = editRange
    }

    /// 安全获取  UITextPosition
    private func safeTextPosition(_ optionlTextPosition: UITextPosition?) -> UITextPosition {

        /* beginningOfDocument -> The end and beginning of the the text document. */
        return optionlTextPosition ?? self.beginningOfDocument
    }
}

extension String {

    /// 比较后 决定 返回 text 还是 safetext
    ///
    /// - Parameters:
    ///   - n: 长度
    ///   - safeText: 安全字符串
    /// - Returns: 返回的值
    fileprivate func safelyLimitedTo(length n: Int, safeText: String?) -> String? {
        if (self.count <= n) {
            return self
        }
        return safeText ?? String( Array(self).prefix(upTo: n) )
    }
}
1
Z King

Arbeiten in Swift4

// SCHRITT 1 setze UITextFieldDelegate

    class SignUPViewController: UIViewController , UITextFieldDelegate {

       @IBOutlet weak var userMobileNoTextFiled: UITextField!

        override func viewDidLoad() {
            super.viewDidLoad()

// SCHRITT 2 Set Delegat
userMobileNoTextFiled.delegate = // Delegierter selbst festlegen }

     func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    //        guard let text = userMobileNoTextFiled.text else { return true }
    //        let newLength = text.count + string.count - range.length
    //        return newLength <= 10
    //    }

// SCHRITT 3 Anruffunktion  

        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            let maxLength = 10          // set your need
            let currentString: NSString = textField.text! as NSString
            let newString: NSString =
                currentString.replacingCharacters(in: range, with: string) as NSString
            return newString.length <= maxLength
        }
    }
1
Keshav Gera

Einfache Lösung ohne Delegat:

TEXT_FIELD.addTarget(self, action: #selector(editingChanged(sender:)), for: .editingChanged)


@objc private func editingChanged(sender: UITextField) {

        if let text = sender.text, text.count >= MAX_LENGHT {
            sender.text = String(text.dropLast(text.count - MAX_LENGHT))
            return
        }
}
1
ober

Hier ist eine Swift 3.2+ Alternative, die unnötige String-Manipulationen vermeidet. In diesem Fall beträgt die maximale Länge 10:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let text = textField.text ?? ""

    return text.count - range.length + string.count <= 10
}
0
Greg Brown

Ich benutze diesen Schritt, um zunächst in viewdidload das delegate texfield zu setzen.

    override func viewDidLoad() {
        super.viewDidLoad()

        textfield.delegate = self

    }

und dann shouldChangeCharactersIn, nachdem Sie UITextFieldDelegate eingefügt haben.

extension viewController: UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
                let newLength = (textField.text?.utf16.count)! + string.utf16.count - range.length
                if newLength <= 8 { 
                    return true
                } else {
                    return false
                }
            }
    }
0
Jeri P.M

Swift 5
Gutschrift: http://www.swiftdevcenter.com/max-character-limit-of-uitextfield-and-allowed-characters-Swift/
Schreiben Sie einfach eine, um die maximale Zeichenlänge festzulegen

 self.textField.maxLength = 10

Für mehr Details hier klicken

0
Ashish Chauhan

Prüfen Sie einfach die Anzahl der Zeichen in der Zeichenfolge

  1. Fügen Sie einen Delegaten hinzu, um den Controller und den zugewiesenen Delegaten anzuzeigen

klasse YorsClassName: UITextFieldDelegate {

}

  1. überprüfen Sie die Anzahl der Zeichen, die für das Textfeld zulässig sind

func textField (_ textField: UITextField, shouldChangeCharactersIn Bereich: NSRange, replacementString Zeichenfolge: String) -> Bool {if textField.text? .count == 1 {return false} return true}

Hinweis: Hier habe ich geprüft, ob in textField nur Zeichen erlaubt sind

0