最大长度 UITextField
Posted
技术标签:
【中文标题】最大长度 UITextField【英文标题】:Max length UITextField 【发布时间】:2014-10-03 02:36:24 【问题描述】:当我尝试How to you set the maximum number of characters that can be entered into a UITextField using swift? 时,我发现如果我使用所有 10 个字符,我也无法删除该字符。
我唯一能做的就是取消操作(将所有字符一起删除)。
有谁知道如何不挡住键盘(这样我就不能添加其他字母/符号/数字,但我可以使用退格键)?
【问题讨论】:
【参考方案1】:在 Swift 5 和 ios 12 中,尝试以下实现 textField(_:shouldChangeCharactersIn:replacementString:)
方法,该方法是 UITextFieldDelegate
协议的一部分:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
guard let textFieldText = textField.text,
let rangeOfTextToReplace = Range(range, in: textFieldText) else
return false
let substringToReplace = textFieldText[rangeOfTextToReplace]
let count = textFieldText.count - substringToReplace.count + string.count
return count <= 10
这段代码最重要的部分是从range
(NSRange
) 到rangeOfTextToReplace
(Range<String.Index>
) 的转换。请参阅此video tutorial,了解为什么这种转换很重要。
要使此代码正常工作,您还应该将textField
的smartInsertDeleteType
值设置为UITextSmartInsertDeleteType.no
。这将防止在执行粘贴操作时插入(不需要的)额外空间。
下面的完整示例代码展示了如何在UIViewController
中实现textField(_:shouldChangeCharactersIn:replacementString:)
:
import UIKit
class ViewController: UIViewController, UITextFieldDelegate
@IBOutlet var textField: UITextField! // Link this to a UITextField in Storyboard
override func viewDidLoad()
super.viewDidLoad()
textField.smartInsertDeleteType = UITextSmartInsertDeleteType.no
textField.delegate = self
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
guard let textFieldText = textField.text,
let rangeOfTextToReplace = Range(range, in: textFieldText) else
return false
let substringToReplace = textFieldText[rangeOfTextToReplace]
let count = textFieldText.count - substringToReplace.count + string.count
return count <= 10
【讨论】:
你只是把这段代码放在你的视图控制器类中吗?还是我必须建立联系? 如果有人需要设置一些条件......你可以这样做...... if (textField .isEqual(mobileNumberTextfield)) guard let text = textField.text else return true let newLength = text.characters.count + string.characters.count - range.length return newLength 对于 Swift 4,text.characters.count
已弃用,使用 text.count
【参考方案2】:
我是这样做的:
func checkMaxLength(textField: UITextField!, maxLength: Int)
if (countElements(textField.text!) > maxLength)
textField.deleteBackward()
代码对我有用。但我使用故事板。在 Storyboard 中,我在 editing changed 上为视图控制器中的文本字段添加了一个操作。
【讨论】:
countElements 已更改为在 Swift 2 中计数,但更改对我有用! 谢谢,您现在可以使用 textField.text?.characters.count,因为 countElements 已更改。 Tks,这个改动效果很好:Swift 2 中的 countElements(textField.text!) 是:textField.text?.characters.count【参考方案3】:Swift 4 更新
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
guard let text = textField.text else return true
let newLength = text.count + string.count - range.length
return newLength <= 10
【讨论】:
【参考方案4】:您可以扩展 UITextField 并添加一个 @IBInspectable
对象来处理它:
SWIFT 5
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)
@objc func fix(textField: UITextField)
if let t = textField.text
textField.text = String(t.prefix(maxLength))
然后在属性检查器上定义它
见Swift 4 original Answer
【讨论】:
漂亮、干净的代码。但是由于某种原因,当您使用表情符号时,这会导致奇怪的编辑行为。每次尝试编辑时,光标都会跳到行尾。 很酷的解决方案 ..thanx 分享!!【参考方案5】:从@Martin 回答中添加更多详细信息
// linked your button here
@IBAction func mobileTFChanged(sender: AnyObject)
checkMaxLength(sender as! UITextField, maxLength: 10)
// linked your button here
@IBAction func citizenTFChanged(sender: AnyObject)
checkMaxLength(sender as! UITextField, maxLength: 13)
func checkMaxLength(textField: UITextField!, maxLength: Int)
// swift 1.0
//if (count(textField.text!) > maxLength)
// textField.deleteBackward()
//
// swift 2.0
if (textField.text!.characters.count > maxLength)
textField.deleteBackward()
【讨论】:
count(textField.text!) 给出错误。您必须使用 textField.text!.characters.count 谢谢@RegisSt-Gelais,这已经是一个旧答案了,我现在更新了【参考方案6】:在 Swift 4 中
文本字段限制为 10 个字符并允许删除(退格)
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
if textField == userNameFTF
let char = string.cString(using: String.Encoding.utf8)
let isBackSpace = strcmp(char, "\\b")
if isBackSpace == -92
return true
return textField.text!.count <= 9
return true
【讨论】:
【参考方案7】:func checkMaxLength(textField: UITextField!, maxLength: Int)
if (textField.text!.characters.count > maxLength)
textField.deleteBackward()
IOS 9 的小改动
【讨论】:
【参考方案8】:斯威夫特 3
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
let nsString = NSString(string: textField.text!)
let newText = nsString.replacingCharacters(in: range, with: string)
return newText.characters.count <= limitCount
【讨论】:
【参考方案9】:如果要覆盖最后一个字母:
let maxLength = 10
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
if range.location > maxLength - 1
textField.text?.removeLast()
return true
【讨论】:
【参考方案10】:我使用IBInspectable
发布了一个解决方案,因此您可以在界面生成器中或以编程方式更改最大长度值。 Check it out here
【讨论】:
【参考方案11】:您可以在 swift 5 或 swift 4 中使用图片如下所示
-
在视图控制器中添加文本字段
将文本连接到 ViewController
在视图ViewController中添加代码
class ViewController: UIViewController , UITextFieldDelegate
@IBOutlet weak var txtName: UITextField!
var maxLen:Int = 8;
override func viewDidLoad()
super.viewDidLoad()
txtName.delegate = self
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
if(textField == txtName)
let currentText = textField.text! + string
return currentText.count <= maxLen
return true;
您可以从 GitHub 下载完整源代码: https://github.com/enamul95/TextFieldMaxLen
【讨论】:
【参考方案12】:斯威夫特 5
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
let MAX_LENGTH = 4
let updatedString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
return updatedString.count <= MAX_LENGTH
【讨论】:
【参考方案13】:斯威夫特 5
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
if textField == myTextFieldName
if range.location > 10
return false
return true
或
func textFieldDidChangeSelection(_ textField: UITextField)
myTextFieldName.text = String(myTextFieldName.text!.prefix(10))
【讨论】:
通过将光标移动到文本字段的开头可以轻松绕过此解决方案。然后你可以再输入两个字符。【参考方案14】:注意这篇文章中提到的 UITextField 的撤消错误:Set the maximum character length of a UITextField
这里是你如何快速修复它
if(range.length + range.location > count(textField.text))
return false;
【讨论】:
如果要支持表情符号等使用: if (range.length + range.location > count(textField.text.utf16)) return false; 【参考方案15】:Here is my version of code. Hope it helps!
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
let invalidCharacters = NSCharacterSet(charactersInString: "0123456789").invertedSet
if let range = string.rangeOfCharacterFromSet(invalidCharacters, options: nil, range:Range<String.Index>(start: string.startIndex, end: string.endIndex))
return false
if (count(textField.text) > 10 && range.length == 0)
self.view.makeToast(message: "Amount entry is limited to ten digits", duration: 0.5, position: HRToastPositionCenter)
return false
else
return true
【讨论】:
我喜欢 Toast UIView 扩展 :)【参考方案16】:我一直在我的一个应用程序中使用此协议/扩展,它的可读性更强。我喜欢它识别退格并明确告诉您字符何时是退格的方式。
需要考虑的一些事项:
1.实现此协议扩展的任何东西都需要指定字符限制。这通常是您的 ViewController,但您可以将字符限制实现为计算属性并返回其他内容,例如您的一个模型的字符数限制。
2。您需要在文本字段的 shouldChangeCharactersInRange 委托方法中调用此方法。否则您将无法通过返回 false 等来阻止文本输入。
3.您可能希望允许退格字符通过。这就是我添加额外功能来检测退格的原因。您的 shouldChangeCharacters 方法可以检查这一点并尽早返回“true”,因此您始终允许退格。
protocol TextEntryCharacterLimited
var characterLimit:Int get
extension TextEntryCharacterLimited
func charactersInTextField(textField:UITextField, willNotExceedCharacterLimitWithReplacementString string:String, range:NSRange) -> Bool
let startingLength = textField.text?.characters.count ?? 0
let lengthToAdd = string.characters.count
let lengthToReplace = range.length
let newLength = startingLength + lengthToAdd - lengthToReplace
return newLength <= characterLimit
func stringIsBackspaceWith(string:String, inRange range:NSRange) -> Bool
if range.length == 1 && string.characters.count == 0 return true
return false
如果你们中的任何人感兴趣,我有一个 Github 存储库,其中我已经采取了一些这种字符限制行为并将其放入 iOS 框架中。您可以实施一个协议来获得类似于 Twitter 的字符限制显示,显示您超出字符限制的程度。
CharacterLimited Framework on Github
【讨论】:
【参考方案17】:由于委托是一对一的关系,我可能出于其他原因想在其他地方使用它,我喜欢限制文本字段的长度,在他们的设置中添加此代码:
required init(coder aDecoder: NSCoder)
super.init(coder: aDecoder)!
setup()
required override init(frame: CGRect)
super.init(frame: frame)
setup()
func setup()
// your setup...
setMaxLength()
let maxLength = 10
private func setMaxLength()
addTarget(self, action: #selector(textfieldChanged(_:)), for: UIControlEvents.editingChanged)
@objc private func textfieldChanged(_ textField: UITextField)
guard let text = text else return
let trimmed = text.characters.prefix(maxLength)
self.text = String(trimmed)
【讨论】:
【参考方案18】:我正在使用这个;
限制为 3 个字符
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
if let txt = textField.text
let currentText = txt + string
if currentText.count > 3
return false
return true
return true
【讨论】:
【参考方案19】:这是我的简单答案,在 Swift 5.0 中使用 iOS 14+ 和 Xcode 12+...
在viewDidLoad()
中添加以下选择器:
override func viewDidLoad()
// Add a target for myTextField, pointing to .editingDidChange
myTextField.addTarget(self, action: #selector(myTextFieldDidChange(_:)), for: .editingChanged)
在你的课堂上,你还可以添加一个可选的字符限制:
// Add an optional character limit
let characterLimit = 100
然后在你的课堂上,添加这个函数:
@objc func myTextFieldDidChange(_ textField: UITextField)
textField.text = String(textField.text!.prefix(self.characterLimit))
这将在您键入时限制您的字符,或在您将文本复制+粘贴到文本字段时。
【讨论】:
【参考方案20】:需要检查现有字符串加上输入是否大于10。
func textField(textField: UITextField!,shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool
NSUInteger newLength = textField.text.length + string.length - range.length;
return !(newLength > 10)
【讨论】:
您的代码错误。 1. 你必须在 Swift(不是 NSUInteger)中用 let 或 var 声明你的常量或变量。 2. textField.text 和 string 是 String 类型。长度不是 Swift 中 String 的属性/方法。以上是关于最大长度 UITextField的主要内容,如果未能解决你的问题,请参考以下文章