我知道还有其他主题,但我似乎无法找到如何实现它。
我试图将UITextField限制为仅5个字符
优选字母数字和 - 和。和_
我已经看过这段代码了
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
}
和
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
}
我只是不知道如何实际实现它或者#34; textfield&#34;我应该换掉我的自定义名为UITextField
答案 0 :(得分:93)
请注意您将在网上看到的有关此问题的大部分示例代码都已过时。
只需将以下内容粘贴到项目中的任何Swift文件中即可。将文件命名为any,例如“Handy.swift”
您的文字字段现在有.maxLength
。
在开发过程中在storyboard中设置该值是完全可以的,或者在应用程序运行时将其设置为代码。
// 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) )
}
}
就这么简单。
(注意:“safelyLimitedTo #length”只是一个调整字符串长度的调用。所有Swift程序员都有自己的扩展名,或者只使用我在那里看到的。)
以上修复了项目中所有文本字段。
如果您只想将一个特定的文字字段简单地限制为“4”,那就是......
class PinCodeEntry: UITextField {
override func didMoveToSuperview() {
super.didMoveToSuperview()
addTarget(self, action: #selector(fixMe), for: .editingChanged)
}
@objc private func fixMe() { text = text?.safelyLimitedTo(length 4) }
}
唷! 这就是它的全部内容。
(顺便说一下,这是一个与UIText相关的非常有用的提示查看, https://stackoverflow.com/a/42333832/294884)
答案 1 :(得分:84)
您的视图控制器应符合UITextFieldDelegate
,如下所示:
class MyViewController: UIViewController, UITextFieldDelegate {
}
设置文本字段的代理:myTextField.delegate = self
textField(_:shouldChangeCharactersInRange:replacementString:)
所有在一起:
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
}
适用于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
}
仅允许将指定字符集输入给定文本字段
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
答案 2 :(得分:17)
快捷键4,只需使用:
public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return range.location < 10
}
答案 3 :(得分:8)
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
}
答案 4 :(得分:6)
我认为扩展对此更为方便。查看完整的答案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
}
}
答案 5 :(得分:4)
由于文本字段地图,上面发布的其他解决方案会产生保留周期。此外,如果没有设置maxLength
属性而不是人工Int.max
构造,则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
}
}
属性应该是可空的;如果更改了maxLength,目标将被设置多次。
这里有一个更新的Swift4解决方案,带有弱映射以防止内存泄漏和其他修复
public function particulars()
{
return $this->hasOne('App\Sale','page_id');
}
and use
$value->particulars->regular_price;
答案 6 :(得分:3)
我的shouldChangeCharactersIn
的Swift 4版本
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
}
答案 7 :(得分:2)
我有一些东西可以添加到Aladin的答案中:
您的视图控制器应符合UITextFieldDelegate
class MyViewController: UIViewController, UITextViewDelegate {
}
设置文本字段的委托: 要设置委托,您可以控制从文本字段拖动到故事板中的视图控制器。我认为这比在代码中设置
在视图控制器中实施该方法:textField(_:shouldChangeCharactersInRange:replacementString:)
答案 8 :(得分:2)
不使用委托的简单解决方案:
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
}
}
答案 9 :(得分:2)
我根据@Frouo给出补充答案。我认为他的回答是最美好的方式。因为它是我们可以重复使用的通用控件。这里没有泄漏问题。
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
}
}
答案 10 :(得分:2)
这个答案适用于Swift 4,并且非常直接,能够让退格通过。
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
return textField.text!.count < 10 || string == ""
}
答案 11 :(得分:1)
在Swift4中工作
//第1步设置UITextFieldDelegate
class SignUPViewController: UIViewController , UITextFieldDelegate {
@IBOutlet weak var userMobileNoTextFiled: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
//第2步设置代理
userMobileNoTextFiled.delegate = self //设置委托
}
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
// }
// STEP 3调用函数
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
}
}
答案 12 :(得分:1)
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) )
}
}
答案 13 :(得分:1)
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
}
答案 14 :(得分:1)
以防万一,在将其应用于字符串之前,请不要忘记保护范围大小。 否则,如果用户执行此操作,则会崩溃:
输入最大长度的文本 插入内容(由于长度限制,不会插入任何内容,但iOS对此一无所知) 撤消插入(您会崩溃,原因范围将大于实际的字符串大小)
此外,使用iOS 13用户可能会通过手势意外触发
我建议您将此添加到您的项目中
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)
}
}
并像这样使用它:
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
}
否则,您将不断崩溃于应用程序中
答案 15 :(得分:0)
这是一个Swift 3.2+替代方案,可以避免不必要的字符串操作。在这种情况下,最大长度为10:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let text = textField.text ?? ""
return text.count - range.length + string.count <= 10
}
答案 16 :(得分:0)
我使用此步骤,首先在viewdidload中设置委托texfield。
override func viewDidLoad() {
super.viewDidLoad()
textfield.delegate = self
}
,然后在包含UITextFieldDelegate之后,应该应该使用ChangeCharactersIn。
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
}
}
}
答案 17 :(得分:0)
只需检查字符串中的字符数
class YorsClassName:UITextFieldDelegate {
}
func textField(_ textField:UITextField,shouldChangeCharacters在范围内:NSRange,replacementString字符串:String)-> Bool { 如果textField.text?.count == 1 { 返回假 } 返回真 }
注意:在这里,我只检查了textField中允许的字符
答案 18 :(得分:0)
雨燕5
信用:http://www.swiftdevcenter.com/max-character-limit-of-uitextfield-and-allowed-characters-swift/
只需写一个即可设置最大字符长度
self.textField.maxLength = 10
更多详情click here
答案 19 :(得分:0)
如果您有多个textField可以在一页上进行各种长度检查,那么我发现了一个简单而又简短的解决方案。
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)
}
}
答案 20 :(得分:0)
1.设置你的文本框的委托:
textField.delegate = self
2.在你的视图控制器中实现该方法:
// MARK: Text field delegate
extension ViewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return range.location < maxLength (maxLength can be any maximum length you can define)
}
}