ios 在 Swift 中设置 UITextField 的最大字符长度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31363216/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set the maximum character length of a UITextField in Swift
提问by ishkur88
I know there are other topics on this but I can't seem to find out how to implement it.
我知道还有其他主题,但我似乎无法找到如何实施它。
I'm trying to limit a UITextField to only 5 Characters
我试图将 UITextField 限制为只有 5 个字符
Preferably Alphanumeric and - and . and _
最好是字母数字和 - 和。和 _
I've seen this code
我见过这个代码
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
}
and
和
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
}
I just don't know how to actually implement it or which "textfield" should I swap out for my custom named UITextField
我只是不知道如何实际实现它,或者我应该为我的自定义命名 UITextField 换出哪个“文本字段”
回答by Aladin
Your view controller should conform to
UITextFieldDelegate
, like below:class MyViewController: UIViewController, UITextFieldDelegate { }
Set the delegate of your textfield:
myTextField.delegate = self
- Implement the method in your view controller :
textField(_:shouldChangeCharactersInRange:replacementString:)
您的视图控制器应符合
UITextFieldDelegate
,如下所示:class MyViewController: UIViewController, UITextFieldDelegate { }
设置文本字段的委托:
myTextField.delegate = self
- 在您的视图控制器中实现该方法:
textField(_:shouldChangeCharactersInRange:replacementString:)
All together:
全部一起:
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
}
For Swift 4
对于 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
}
Allowing only a specified set of characters to be entered into a given text field
只允许在给定的文本字段中输入一组指定的字符
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
}
How to program an iOS text field that takes only numeric input with a maximum length
回答by Fattie
Dec 2017. Swift 4.
2017 年 12 月。斯威夫特 4。
Take care that much of the example code which you will see online regarding this problem is very out of date.
请注意,您将在网上看到的有关此问题的大部分示例代码已经过时。
Paste the following into any Swift file in your project. You can name the file anything, for example, "Handy.swift"
将以下内容粘贴到项目中的任何 Swift 文件中。您可以将文件命名为任何名称,例如“Handy.swift”
This finally fixes one of the stupidest problems in iOS:
这最终解决了 iOS 中最愚蠢的问题之一:
Your text fields now have a .maxLength
.
您的文本字段现在有一个.maxLength
.
It is completely OK to set that value in storyboard during development, or, set it in code while the app is running.
在开发期间在故事板中设置该值是完全可以的,或者在应用程序运行时在代码中设置它。
// 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)
}
}
It's that simple.
就这么简单。
Footnote - these days to safely truncate a String
in swift, you simply .prefix(n)
脚注 - 这些天来安全地String
在 swift 中截断 a ,您只需.prefix(n)
An even simpler one-off version...
一个更简单的一次性版本......
The above fixes alltext fields in your project.
以上修复了项目中的所有文本字段。
If you just want one particulartext field to simply be limited to say "4", and that's that...
如果您只想将一个特定的文本字段简单地限制为“4”,那就是...
class PinCodeEntry: UITextField {
override func didMoveToSuperview() {
super.didMoveToSuperview()
addTarget(self, action: #selector(fixMe), for: .editingChanged)
}
@objc private func fixMe() { text = text?.prefix(4) }
}
Phew! That's all there is to it.
呼!这里的所有都是它的。
(Just BTW, here's a similar very useful tip relating to UITextView, https://stackoverflow.com/a/42333832/294884)
(顺便说一句,这里有一个与 UIText View相关的非常有用的类似提示, https://stackoverflow.com/a/42333832/294884 )
回答by Сергей Билык
Swift 4, simply use:
Swift 4,只需使用:
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return range.location < 10
}
回答by Pavlos
The same way Steven Schmatz did it but using Swift 3.0 :
与 Steven Schmatz 的做法相同,但使用的是 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
}
回答by ZaEeM ZaFaR
I think extension is more handy for this. See full answer here
我认为扩展对此更方便。在此处查看完整答案
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
}
}
回答by Ashish Chauhan
Swift 5
Credit: http://www.swiftdevcenter.com/max-character-limit-of-uitextfield-and-allowed-characters-swift/
Just write one to set max char length
Swift 5
Credit: http://www.swiftdevcenter.com/max-character-limit-of-uitextfield-and-allowed-characters-swift/
只需写一个来设置最大字符长度
self.textField.maxLength = 10
For more detial click here
更多详情请点击这里
回答by Angel G. Olloqui
Other solutions posted above produce a retain cycle due to the textfield map. Besides, the maxLength
property should be nullable if not set instead of artificial Int.max
constructions; and the target will be set multiple times if maxLength is changed.
由于文本字段映射,上面发布的其他解决方案会产生一个保留周期。此外,maxLength
如果不设置而不是人工Int.max
构造,则该属性应该可以为空;如果 maxLength 改变,目标将被设置多次。
Here an updated solution for Swift4 with a weak map to prevent memory leaks and the other fixes
这是Swift4的更新解决方案,带有弱映射以防止内存泄漏和其他修复
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
}
}
回答by ober
Simple solution without using 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
}
}
回答by aviran
My Swift 4 version of shouldChangeCharactersIn
我的 Swift 4 版本 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
}
回答by zheng
update for this Fattie answer
更新此Fattie 答案
thanks
谢谢
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
}
}