Ich weiß, dass es noch andere Themen gibt, aber ich kann anscheinend nicht herausfinden, wie ich es implementieren soll.
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ß nur nicht, wie ich es tatsächlich implementieren soll oder welches "Textfeld" ich gegen mein benutzerdefiniertes UITextField austauschen soll
String
in Swift in diesen Tagen zu verkürzen , können Sie endlich nur .prefix (n)Antworten:
Ihr View Controller sollte wie folgt übereinstimmen
UITextFieldDelegate
:class MyViewController: UIViewController, UITextFieldDelegate { }
Legen Sie den Delegaten Ihres Textfelds fest:
myTextField.delegate = self
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 }
Zulassen, dass nur ein bestimmter Zeichensatz in ein bestimmtes Textfeld eingegeben wird
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 maximaler Länge akzeptiert
quelle
textField
in der Methodefunc textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
shouldChangeCharactersInRange
aufgerufen. Dies gilt für alle Textfelder. Sie erhalten den Rückruf an derselben Stelle.shouldChangeCharactersInRange
Innerhalb dieser Methode können Sie dank des übergebenen Parameters, dentextField
Sie beispielsweise angeben können, feststellen, welches Textfeld bearbeitet wird Tag für jedes Textfeld und Test innerhalb desshouldChangeCharactersInRange
und für jedes Textfeld führen Sie die Validierung des Inhalts durchDezember 2017. Swift 4.
Achten Sie darauf, dass ein Großteil des Beispielcodes, den Sie online zu diesem Problem sehen, sehr veraltet ist .
Fügen Sie Folgendes in eine beliebige Swift-Datei in Ihrem Projekt ein. Sie können der Datei einen beliebigen Namen geben, z. B. "Handy.swift".
Dies behebt schließlich eines der dümmsten Probleme in iOS:
Ihre Textfelder haben jetzt eine
.maxLength
.Es ist völlig in Ordnung, diesen Wert während der Entwicklung im Storyboard oder während der Ausführung der App im Code festzulegen.
// 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?.prefix(maxLength) } }
So einfach ist das.
Fußnote - heutzutage, um ein
String
schnelles sicheres Abschneiden zu erreichen, müssen Sie einfach.prefix(n)
Eine noch einfachere einmalige Version ...
Das obige korrigiert alle Textfelder in Ihrem Projekt.
Wenn Sie nur möchten, dass ein bestimmtes Textfeld einfach auf "4" beschränkt ist, dann ist das ...
class PinCodeEntry: UITextField { override func didMoveToSuperview() { super.didMoveToSuperview() addTarget(self, action: #selector(fixMe), for: .editingChanged) } @objc private func fixMe() { text = text?.prefix(4) } }
Puh! Das ist alles dazu.
(Übrigens, hier ist ein ähnlicher sehr nützlicher Tipp in Bezug auf UIText View , https://stackoverflow.com/a/42333832/294884 )
Für den OCD-Programmierer (wie ich) ...
Wie @LeoDabus erinnert, gibt .prefix einen Teilstring zurück. Wenn Sie sich unglaublich sorgen, ist dies
let t = textField.text textField.text = t?.prefix(maxLength)
wäre
if let t: String = textField.text { textField.text = String(t.prefix(maxLength)) }
Genießen!
quelle
Swift 4, benutze einfach:
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { return range.location < 10 }
quelle
string.count < MAX_LENGTH
Genauso wie Steven Schmatz es getan hat, 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 }
quelle
Für Swift 5:
Schreiben Sie einfach eine Zeile, um die maximale Zeichenlänge festzulegen:
self.textField.maxLength = 10
Für weitere Details klicken Sie hier
Gutschrift: http://www.swiftdevcenter.com/max-character-limit-of-uitextfield-and-allowed-characters-swift/
quelle
Ich denke, Erweiterung ist dafür praktischer. Die vollständige Antwort finden Sie 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 } }
quelle
Andere oben angegebene Lösungen erzeugen aufgrund der Textfeldkarte einen Aufbewahrungszyklus. Außerdem sollte die
maxLength
Eigenschaft nullbar sein, wenn sie nicht anstelle künstlicherInt.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 Map, um Speicherlecks 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 } }
quelle
Einfache Lösung ohne Delegate:
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 } }
quelle
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 }
quelle
Ich habe Aladins Antwort etwas hinzuzufügen:
Ihr View Controller sollte den Anforderungen entsprechen
UITextFieldDelegate
class MyViewController: UIViewController, UITextViewDelegate { }
Festlegen des Delegaten Ihres Textfelds: Um den Delegaten festzulegen, können Sie das Ziehen vom Textfeld auf Ihren Ansichtscontroller im Storyboard steuern. Ich denke, dies ist der Einstellung im Code vorzuziehen
Implementieren Sie die Methode in Ihrem View Controller:
textField(_:shouldChangeCharactersInRange:replacementString:)
quelle
Ich gebe eine ergänzende Antwort basierend auf @Frouo. Ich denke, seine Antwort ist der schönste Weg. Weil es eine übliche 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 } }
quelle
Update für diese Fattie-Antwort
Vielen Dank
extension UITextField { /// Runtime key private struct AssociatedKeys { /// max lenght key static var maxlength: UInt8 = 0 /// temp string key static var tempString: UInt8 = 0 } /// Limit the maximum input length of the textfiled @IBInspectable var maxLength: Int { get { return objc_getAssociatedObject(self, &AssociatedKeys.maxlength) as? Int ?? 0 } set { objc_setAssociatedObject(self, &AssociatedKeys.maxlength, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) addTarget(self, action: #selector(handleEditingChanged(textField:)), for: .editingChanged) } } /// temp string private var tempString: String? { get { return objc_getAssociatedObject(self, &AssociatedKeys.tempString) as? String } set { objc_setAssociatedObject(self, &AssociatedKeys.tempString, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } /// When the text changes, process the amount of text in the input box so that its length is within the controllable range. @objc private func handleEditingChanged(textField: UITextField) { /// Special Processing for Chinese Input Method guard markedTextRange == nil else { return } if textField.text?.count == maxLength { /// SET lastQualifiedString where text length == max lenght tempString = textField.text } else if textField.text?.count ?? 0 < maxLength { /// clear lastQualifiedString when text lengeht > maxlength tempString = nil } /// keep current text range in arcgives let archivesEditRange: UITextRange? if textField.text?.count ?? 0 > maxLength { /// if text length > maxlength,remove last range,to move to -1 postion. let position = textField.position(from: safeTextPosition(selectedTextRange?.start), offset: -1) ?? textField.endOfDocument archivesEditRange = textField.textRange(from: safeTextPosition(position), to: safeTextPosition(position)) } else { /// just set current select text range archivesEditRange = selectedTextRange } /// main handle string max length textField.text = tempString ?? String((textField.text ?? "").prefix(maxLength)) /// last config edit text range textField.selectedTextRange = archivesEditRange } /// get safe textPosition private func safeTextPosition(_ optionlTextPosition: UITextPosition?) -> UITextPosition { /* beginningOfDocument -> The end of the the text document. */ return optionlTextPosition ?? endOfDocument } }
quelle
Arbeiten in Swift4
// SCHRITT 1 setze UITextFieldDelegate
class SignUPViewController: UIViewController , UITextFieldDelegate { @IBOutlet weak var userMobileNoTextFiled: UITextField! override func viewDidLoad() { super.viewDidLoad()
//
SCHRITT 2 Delegat setzen userMobileNoTextFiled.delegate = self // Delegat setzen}
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 Funktion aufrufen
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 } }
quelle
Diese Antwort ist für Swift 4 und ist ziemlich einfach mit der Fähigkeit, die Rücktaste durchzulassen.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { return textField.text!.count < 10 || string == "" }
quelle
Überprüfen Sie einfach die Anzahl der Zeichen in der Zeichenfolge
class YorsClassName : UITextFieldDelegate { }
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if textField.text?.count == 1 { return false } return true }
Hinweis: Hier habe ich nur nach Zeichen gesucht, die in textField zulässig sind
quelle
TextField-Begrenzungszeichen nach dem Blockieren des Texts in Swift 4
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,replacementString string: String) -> Bool { if textField == self.txtDescription { let maxLength = 200 let currentString: NSString = textField.text! as NSString let newString: NSString = currentString.replacingCharacters(in: range, with: string) as NSString return newString.length <= maxLength } return true }
quelle
Vergessen Sie für alle Fälle nicht, die Bereichsgröße zu schützen, bevor Sie sie auf die Zeichenfolge anwenden. Andernfalls kommt es zum Absturz, wenn der Benutzer dies tut:
Text mit maximaler Länge eingeben Etwas einfügen (Aufgrund der Längenbeschränkung wird nichts eingefügt, aber iOS weiß nichts davon.) Einfügen rückgängig machen (Sie stürzen ab, da der Bereich größer als die tatsächliche Zeichenfolgengröße ist.)
Bei Verwendung von iOS 13 können Benutzer dies versehentlich durch Gesten auslösen
Ich schlage vor, dass Sie dies zu Ihrem Projekt hinzufügen
extension String { func replace(with text: String, in range: NSRange) -> String? { guard range.location + range.length <= self.count else { return nil } return (self as NSString).replacingCharacters(in: range, with: text) } }
Und benutze es so:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { guard let newText = textView.text.replace(with: text, in: range) else { return false } return newText.count < maxNumberOfCharacters }
Andernfalls stürzt Ihre App ständig ab
quelle
Hier ist eine Swift 3.2+ Alternative, die unnötige Manipulationen an Zeichenfolgen 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 }
quelle
Ich benutze diesen Schritt, zuerst setze delegate texfield in viewdidload.
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 } } }
quelle
Wenn Sie mehrere Textfelder mit verschiedenen Längenprüfungen auf einer Seite haben, habe ich eine einfache und kurze Lösung gefunden.
class MultipleTextField: UIViewController { let MAX_LENGTH_TEXTFIELD_A = 10 let MAX_LENGTH_TEXTFIELD_B = 11 lazy var textFieldA: UITextField = { let textField = UITextField() textField.tag = MAX_LENGTH_TEXTFIELD_A textField.delegate = self return textField }() lazy var textFieldB: UITextField = { let textField = UITextField() textField.tag = MAX_LENGTH_TEXTFIELD_B textField.delegate = self return textField }() } extension MultipleTextField: UITextFieldDelegate { func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { return (range.location < textField.tag) && (string.count < textField.tag) } }
quelle