【发布时间】:2010-09-30 19:20:27
【问题描述】:
当我加载 UIView 时,如何在 iPhone SDK 上设置 UITextField 中的最大字符数?
【问题讨论】:
-
这个令人难以置信的旧答案已经过时了 - 现在答案很简单:stackoverflow.com/a/38306929/294884
标签: ios objective-c cocoa-touch uitextfield
当我加载 UIView 时,如何在 iPhone SDK 上设置 UITextField 中的最大字符数?
【问题讨论】:
标签: ios objective-c cocoa-touch uitextfield
如果您限制文本计数的目的是确保文本适合其他地方的 UILabel,我会避免使用字符计数。它会因一些表情符号而崩溃(尝试截断双倍大小的表情符号可能会使您的应用程序崩溃)。这也是一些语言(如日语和中文)的问题,它们有两步输入过程,简单的计数是行不通的。
我构建了一个 UITextField 插入子类 (MPC_CharacterLimitedTextField on github)。你给它提供预期的输出标签宽度,它会处理所有语言、表情符号和粘贴问题。无论字符数如何,它都只会收集适合标签的完整字符。该项目中有一个演示,因此您可以对其进行测试以查看它是否是您所需要的。希望它会帮助任何在输出长度方面遇到与我相同问题的人。
【讨论】:
您也可以使用 Swift 4 中的 NotificationCenter 来完成此操作
NotificationCenter.default.addObserver(self, selector: #selector(self.handleTextChange(recognizer:)), name: NSNotification.Name.UITextFieldTextDidChange, object: yourTextField)
@objc func handleTextChange(recognizer: NSNotification) {
//max length is 50 charater max
let textField = recognizer.object as! UITextField
if((textField.text?.count)! > 50) {
let newString: String? = (textField.text as NSString?)?.substring(to: 50)
textField.text = newString
}
}
【讨论】:
Swift 4.2 和 UITextFieldDelegate 方法
这对我有用,并将文本字段的最大输入限制为 8 个字符。希望 NSRange 最终会更改为 Range,但现在我很高兴使用 NSString,因为从 NSRange 创建 Range 涉及到处理另一个可选项。
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let text = textField.text ?? ""
let nsString = text as NSString
let newText = nsString.replacingCharacters(in: range, with: string)
return newText.count <= 8
}
【讨论】:
上面给出的一些答案的问题是,例如我有一个文本字段,我必须设置输入 15 个字符的限制,然后在输入第 15 个字符后停止。但他们不允许删除。那就是删除按钮也不起作用。因为我面临同样的问题。提出了解决方案,如下所示。非常适合我
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if(textField.tag==6)
{
if ([textField.text length]<=30)
{
return YES;
}
else if([@"" isEqualToString:string])
{
textField.text=[textField.text substringToIndex:30 ];
}
return NO;
}
else
{
return YES;
}
}
我有一个文本字段,我已将其标记设置为“6” 我已经限制了最大字符限制 = 30; 在任何情况下都可以正常工作
【讨论】:
(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if ([txt_name.text length]>100)
{
return NO;
}
return YES;
}
【讨论】:
这限制了字符数,但还要确保您可以在字段中粘贴直到最大限制。
- (void)textViewDidChange:(UITextView *)textView
{
NSString* str = [textView text];
str = [str substringToIndex:MIN(1000,[str length])];
[textView setText:str];
if([str length]==1000) {
// show some label that you've reached the limit of 1000 characters
}
}
【讨论】:
除了回答原始问题并扩展 Frouo 的答案之外,这里有一些扩展来修剪空格字符串和最大长度,并利用这些字符串扩展来修剪 UITextField 到最大长度:
// In String_Extensions.swift
extension String {
func trimmedString() -> String {
var trimmedString = self.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
let components = trimmedString.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()).filter { count($0) > 0 }
return " ".join(components)
}
func trimmedStringToMaxLength(maxLength: Int) -> String {
return trimmedString().substringToIndex(advance(startIndex, min(count(self), maxLength))).trimmedString()
}
}
// In UITextField_Extensions.swift
private var maxLengthDictionary = [UITextField : Int]()
private var textFieldMaxLength = 20
extension UITextField {
@IBInspectable var maxLength: Int {
get {
if let maxLength = maxLengthDictionary[self] {
return maxLength
} else {
return textFieldMaxLength
}
}
set {
maxLengthDictionary[self] = newValue < textFieldMaxLength + 1 ? newValue : textFieldMaxLength
}
}
func trimAndLimitToMaxLength() {
text = text.trimmedStringToMaxLength(maxLength)
}
}
let someTextField = UITextField()
let someString = " This is a string that is longer than allowable for a text field. "
someTextField.text = someString
someTextField.trimAndLimitToMaxLength()
println(someTextField.text) // Prints "This is a string tha"
let anotherTextField = UITextField()
anotherTextField.maxLength = 5
anotherTextField.text = someString
anotherTextField.trimAndLimitToMaxLength()
println(anotherTextField.text) // Prints "This"
trimAndLimitToMaxLength() 可以在 UITextFieldDelegate 的textFieldDidEndEditing(_:) 中使用,以便用户可以输入或粘贴比可接受的更长的字符串,然后将其缩短而不是仅以最大长度切断输入。为此,我还将设置属性文本样式以指示超出可接受长度的任何文本部分(例如,[NSBackgroundColorAttributeName : UIColor.redColor(), NSForegroundColorAttributeName : UIColor.whiteColor(), NSStrikethroughStyleAttributeName : NSNumber(int: 1)]
【讨论】:
我们可以像这样设置文本字段的范围..
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
int setrange = 20;
return !([textField.text length]>setrange && [string length] > range.length);
}
【讨论】:
对于 Swift 2.1+
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if (range.length + range.location > textField.text!.characters.count )
{
return false;
}
let newLength = textField.text!.characters.count + string.characters.count - range.length
return newLength <= 25
}
希望对你有帮助
【讨论】:
我想补充@sickp 给出的答案。
他的Swift 代码中存在一个问题,该问题出现在任何多字节文本(例如表情符号)中。 NSRange 和 Swift 中的 String 不兼容,因此委托类将它们结合起来令人沮丧。诀窍是将String 对象转换为NSString 根据@sickp 所写的内容,正确的解决方案实际上是这样的:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let currentText = (textField.text as NSString?) ?? NSString()
let currentCharacterCount = currentText.length
if range.length + range.location > currentCharacterCount {
return false
}
let newLength = currentText.replacingCharacters(in: range, with: string).characters.count
return newLength <= 25
}
【讨论】:
适用于 Swift 3.1 或更高版本
首先添加协议UITextFieldDelegate
喜欢:-
class PinCodeViewController: UIViewController, UITextFieldDelegate {
.....
.....
.....
}
之后创建你的 UITextField 并设置委托
完整的经验:-
import UIKit
class PinCodeViewController: UIViewController, UITextFieldDelegate {
let pinCodetextField: UITextField = {
let tf = UITextField()
tf.placeholder = "please enter your pincode"
tf.font = UIFont.systemFont(ofSize: 15)
tf.borderStyle = UITextBorderStyle.roundedRect
tf.autocorrectionType = UITextAutocorrectionType.no
tf.keyboardType = UIKeyboardType.numberPad
tf.clearButtonMode = UITextFieldViewMode.whileEditing;
tf.contentVerticalAlignment = UIControlContentVerticalAlignment.center
return tf
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(pinCodetextField)
//----- setup your textfield anchor or position where you want to show it-----
// after that
pinCodetextField.delegate = self // setting the delegate
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return !(textField.text?.characters.count == 6 && string != "")
} // this is return the maximum characters in textfield
}
【讨论】:
在 Swift 5.2 中工作:
class AngListVC: UIViewController, UITextFieldDelegate {
@IBOutlet weak var angTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
angTextField.delegate = self
angTextField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let userText = angTextField.text ?? ""
var newText = ""
if range.length > 0 {
let txt = NSString(string: userText)
if txt.length > 0 {
newText = txt.replacingCharacters(in: range, with: "")
}
} else {
newText = userText + ""
}
return newText.count <= 3
}
@objc func textFieldDidChange(_ textField: UITextField) {
print("textFieldDidChange")
}
【讨论】:
对于 Swift 5
添加这个 UITextfield 的扩展,然后选择一个文本域并检查属性检查器
private var __maxLengths = [UITextField: Int]()
extension UITextField {
@IBInspectable var maxLength: Int {
get {
guard let l = __maxLengths[self] else {
return 150 // (default int limit)
}
return l
}
set {
__maxLengths[self] = newValue
addTarget(self, action: #selector(setMaxLength), for: .editingChanged)
}
}
@objc func setMaxLength(textField: UITextField) {
let t = textField.text
textField.text = t?.prefix(maxLength).description
}
}
【讨论】:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (textField.text.length >= 50) {
return NO;
}
return YES;
}
【讨论】:
Swift 4.2+
通过实现UITextFieldDelegate方法
视图控制器:
class MyViewController: UIViewController {
let MAX_LENGTH = 256
@IBOutlet weak var myTextField: UITextField!
override viewDidLoad() {
self.myTextField.delegate = self
}
}
代表:
extension MyViewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let userText = textView.text ?? ""
var newText = ""
if range.length > 0 {
let txt = NSString(string: userText)
if txt.length > 0 {
newText = txt.replacingCharacters(in: range, with: text)
}
} else {
newText = userText + text
}
return newText.count <= MAX_LENGTH
}
}
【讨论】:
我发现这个快速简单
- (IBAction)backgroundClick:(id)sender {
if (mytext.length <= 7) {
[mytext resignFirstResponder];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Too Big"
message:@"Please Shorten Name"
delegate:nil
cancelButtonTitle:@"Cancel"
otherButtonTitles:nil];
[alert show];
[alert release];
}
}
【讨论】:
UIAlertViews。您应该为重要消息保留警报,并且只允许输入,就像在接受的答案中一样。