을 UITextField
올릴 때 iPhone SDK 에서 최대 문자 수를 어떻게 설정 UIView
합니까?
을 UITextField
올릴 때 iPhone SDK 에서 최대 문자 수를 어떻게 설정 UIView
합니까?
답변:
그동안 UITextField
클래스에는 최대 길이 속성이 없습니다, 그것은 텍스트 필드의를 설정하여이 기능을 얻기 위해 상대적으로 간단 delegate
하고 다음 대리자 메서드를 구현 :
목표 -C
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// Prevent crashing undo bug – see note below.
if(range.length + range.location > textField.text.length)
{
return NO;
}
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return newLength <= 25;
}
빠른
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let currentCharacterCount = textField.text?.count ?? 0
if range.length + range.location > currentCharacterCount {
return false
}
let newLength = currentCharacterCount + string.count - range.length
return newLength <= 25
}
텍스트 필드가 변경되기 전에 UITextField는 지정된 텍스트 를 변경 해야하는지 대리인에게 묻습니다 . 이 시점에서 텍스트 필드는 변경되지 않았으므로 현재 길이와 삽입 할 문자열 길이 (복사 된 텍스트 붙여 넣기 또는 키보드를 사용하여 단일 문자 입력)를 빼고 범위 길이를 뺀 것입니다. 이 값이 너무 길면 (이 예에서는 25 자 이상) NO
변경을 금지하기 위해 돌아가십시오 .
텍스트 필드의 끝에 단일 문자를 입력 range.location
하면 현재 필드의 길이가되고 range.length
어떤 것도 바꾸거나 삭제하지 않기 때문에 0이됩니다. 텍스트 필드의 중간에 삽입한다는 것은 다른 것을 의미하며 range.location
여러 문자를 붙여 넣으면 string
둘 이상의 문자가 있음을 의미 합니다.
단일 문자 삭제 또는 여러 문자 절단은 range
길이가 0이 아닌 빈 문자열로 지정됩니다. 교체는 비어 있지 않은 문자열로 범위를 삭제하는 것입니다.
주석에서 언급했듯이 UITextField
충돌이 발생할 수 있는 버그 가 있습니다.
필드에 붙여 넣지 만 유효성 검사 구현으로 붙여 넣기가 금지 된 경우 붙여 넣기 작업은 여전히 응용 프로그램의 실행 취소 버퍼에 기록됩니다. 당신이 후 (장치를 흔들어 실행 취소를 확인하여) 실행 취소를 해고하는 경우는 UITextField
이 문자열 대체하려고 시도합니다 생각 이 빈 문자열 자체에 붙여 넣기합니다. 실제로 문자열을 자체적으로 붙여 넣지 않았기 때문에 충돌이 발생 합니다. 존재하지 않는 문자열의 일부를 바꾸려고 시도합니다.
다행스럽게도 UITextField
이와 같이 자신을 죽이지 않도록 보호 할 수 있습니다 . 당신은 그것을 대체하는 제안의 범위가 있는지 확인해야 합니까 현재 문자열 내에 존재합니다. 이것이 위의 초기 상태 점검입니다.
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
let str = (textView.text + text)
if str.characters.count <= 10 {
return true
}
textView.text = str.substring(to: str.index(str.startIndex, offsetBy: 10))
return false
}
도움이 되길 바랍니다.
return newLength <= 25;
UITextField
iPad iOS 8.1에서 테스트되었습니다 . (댓글을 달려면 +1). 작성자가 최고 등급의 답변이므로 이에 대해 뭔가 추가 하시겠습니까? 편집을하게되어 기쁘지만 정기적으로 거부당하는 것 같습니다! :-)
import UIKit
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)
addTarget(self, action: #selector(checkMaxLength), for: .editingChanged)
}
}
@objc func checkMaxLength(textField: UITextField) {
guard let prospectiveText = self.text,
prospectiveText.count > maxLength
else {
return
}
let selection = selectedTextRange
let indexEndOfText = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
let substring = prospectiveText[..<indexEndOfText]
text = String(substring)
selectedTextRange = selection
}
}
편집 : 메모리 누수 문제가 해결되었습니다.
8 월 감사합니다! ( 포스트 )
이것은 내가 끝낸 코드입니다.
#define MAX_LENGTH 20
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField.text.length >= MAX_LENGTH && range.length == 0)
{
return NO; // return NO to not change text
}
else
{return YES;}
}
return textField.text.length < MAX_LENGTH || range.length != 0;
제안 된 함수의 가능한 구현 인 8 월 답변 을 완료하려면 ( UITextField의 delegate 참조 ).
나는 돔 코드를 테스트 하지 않았지만 사용자가 한계에 도달하면 멈추지 않으며 더 작거나 같은 것을 대체하는 새로운 문자열과 호환됩니다.
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
//limit the size :
int limit = 20;
return !([textField.text length]>limit && [string length] > range.length);
}
직접 할 수 UITextField
는 없습니다 -maxLength 속성이 없지만 UITextField's
대리자를 설정 한 후 다음을 사용할 수 있습니다.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
종종 길이가 다른 여러 입력 필드가 있습니다.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
int allowedLength;
switch(textField.tag) {
case 1:
allowedLength = MAXLENGTHNAME; // triggered for input fields with tag = 1
break;
case 2:
allowedLength = MAXLENGTHADDRESS; // triggered for input fields with tag = 2
break;
default:
allowedLength = MAXLENGTHDEFAULT; // length default when no tag (=0) value =255
break;
}
if (textField.text.length >= allowedLength && range.length == 0) {
return NO; // Change not allowed
} else {
return YES; // Change allowed
}
}
가장 좋은 방법은 텍스트 변경에 대한 알림을 설정하는 것입니다. 당신의에서 -awakeFromNib
보기 컨트롤러 방법 당신이 원하는 것 :
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(limitTextField:) name:@"UITextFieldTextDidChangeNotification" object:myTextField];
그런 다음 동일한 클래스에서 다음을 추가하십시오.
- (void)limitTextField:(NSNotification *)note {
int limit = 20;
if ([[myTextField stringValue] length] > limit) {
[myTextField setStringValue:[[myTextField stringValue] substringToIndex:limit]];
}
}
그런 다음 콘센트 myTextField
를 귀하 의 콘센트 에 연결 UITextField
하면 한도에 도달 한 후 더 이상 문자를 추가 할 수 없습니다. 이것을 dealloc 메소드에 추가하십시오 :
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"UITextFieldTextDidChangeNotification" object:myTextField];
이 UITextFieldLimit 하위 클래스를 만들었습니다 .
그랩 UITextFieldLimit.h
과 UITextFieldLimit.m
이 GitHub의 저장소에서를 :
https://github.com/JonathanGurebo/UITextFieldLimit
테스트 시작!
스토리 보드에서 만든 UITextField를 표시하고 Identity Inspector를 사용하여 내 하위 클래스에 연결하십시오.
그런 다음 IBOutlet에 연결하고 한계를 설정할 수 있습니다 (기본값은 10).
ViewController.h 파일에는 다음이 포함되어야합니다 (한계와 같이 설정을 수정하지 않으려는 경우).
#import "UITextFieldLimit.h"
/.../
@property (weak, nonatomic) IBOutlet UITextFieldLimit *textFieldLimit; // <--Your IBOutlet
ViewController.m 파일이 있어야합니다 @synthesize textFieldLimit
.
ViewController.m 파일에서 텍스트 길이 제한을 설정하십시오.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[textFieldLimit setLimit:25];// <-- and you won't be able to put more than 25 characters in the TextField.
}
수업이 도움이 되길 바랍니다. 행운을 빕니다!
이것은 문제를 해결하기에 충분해야합니다 (원하는 한계 값으로 4를 대체하십시오). IB에 대리인을 추가하십시오.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
return (newString.length<=4);
}
아래 확장명을 사용하여 a UITextField
및 의 최대 문자 길이를 설정하십시오 UITextView
.
스위프트 4.0
private var kAssociationKeyMaxLength: Int = 0
private var kAssociationKeyMaxLengthTextView: 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)
addTarget(self, action: #selector(checkMaxLength), for: .editingChanged)
}
}
@objc func checkMaxLength(textField: UITextField) {
guard let prospectiveText = self.text,
prospectiveText.count > maxLength
else {
return
}
let selection = selectedTextRange
let indexEndOfText = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
let substring = prospectiveText[..<indexEndOfText]
text = String(substring)
selectedTextRange = selection
}
}
extension UITextView:UITextViewDelegate {
@IBInspectable var maxLength: Int {
get {
if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLengthTextView) as? Int {
return length
} else {
return Int.max
}
}
set {
self.delegate = self
objc_setAssociatedObject(self, &kAssociationKeyMaxLengthTextView, newValue, .OBJC_ASSOCIATION_RETAIN)
}
}
public func textViewDidChange(_ textView: UITextView) {
checkMaxLength(textField: self)
}
@objc func checkMaxLength(textField: UITextView) {
guard let prospectiveText = self.text,
prospectiveText.count > maxLength
else {
return
}
let selection = selectedTextRange
let indexEndOfText = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
let substring = prospectiveText[..<indexEndOfText]
text = String(substring)
selectedTextRange = selection
}
}
아래에서 제한을 설정할 수 있습니다.
미래의 문자열 길이를 계산하기 위해 실제 문자열 교체를 시뮬레이션합니다.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
if([newString length] > maxLength)
return NO;
return YES;
}
Swift 3 버전 // ***** Swift 2.x에서는 작동하지 않습니다! ***** //
먼저 새 Swift 파일 (TextFieldMaxLength.swift)을 만든 다음 아래 코드를 추가하십시오.
import UIKit
private var maxLengths = [UITextField: Int]()
extension UITextField {
@IBInspectable var maxLength: Int {
get {
guard let length = maxLengths[self]
else {
return Int.max
}
return length
}
set {
maxLengths[self] = newValue
addTarget(
self,
action: #selector(limitLength),
for: UIControlEvents.editingChanged
)
}
}
func limitLength(textField: UITextField) {
guard let prospectiveText = textField.text,
prospectiveText.characters.count > maxLength
else {
return
}
let selection = selectedTextRange
let maxCharIndex = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
text = prospectiveText.substring(to: maxCharIndex)
selectedTextRange = selection
}
}
TextField를 선택하면 Storyboard에 새 필드 (최대 길이)가 표시됩니다.
그래도 더 궁금한 점이 있으면 다음 링크를 확인 하십시오. -최대 길이-시각-스튜디오 스타일 /
인터페이스 빌더를 사용하면 모든 기능에서 "편집 된 변경 사항"이벤트를 링크하고 얻을 수 있습니다. 이제 길이를 확인할 수 있습니다
- (IBAction)onValueChange:(id)sender
{
NSString *text = nil;
int MAX_LENGTH = 20;
switch ([sender tag] )
{
case 1:
{
text = myEditField.text;
if (MAX_LENGTH < [text length]) {
myEditField.text = [text substringToIndex:MAX_LENGTH];
}
}
break;
default:
break;
}
}
다음 코드는 sickp의 답변과 비슷하지만 복사-붙여 넣기 작업을 올바르게 처리합니다. 한도보다 긴 텍스트를 붙여 넣으려고하면 다음 코드는 붙여 넣기 작업을 완전히 거부하지 않고 한도에 맞게 텍스트를 자릅니다.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
static const NSUInteger limit = 70; // we limit to 70 characters
NSUInteger allowedLength = limit - [textField.text length] + range.length;
if (string.length > allowedLength) {
if (string.length > 1) {
// get at least the part of the new string that fits
NSString *limitedString = [string substringToIndex:allowedLength];
NSMutableString *newString = [textField.text mutableCopy];
[newString replaceCharactersInRange:range withString:limitedString];
textField.text = newString;
}
return NO;
} else {
return YES;
}
}
Swift에서 최대 길이를 설정하는 일반적인 해결책 이 있습니다 . IBInspectable을 통해 Xcode 속성 관리자에서 새 속성을 추가 할 수 있습니다.
import UIKit
private var maxLengths = [UITextField: Int]()
extension UITextField {
@IBInspectable var maxLength: Int {
get {
guard let length = maxLengths[self]
else {
return Int.max
}
return length
}
set {
maxLengths[self] = newValue
addTarget(
self,
action: Selector("limitLength:"),
forControlEvents: UIControlEvents.EditingChanged
)
}
}
func limitLength(textField: UITextField) {
guard let prospectiveText = textField.text
where prospectiveText.characters.count > maxLength else {
return
}
let selection = selectedTextRange
text = prospectiveText.substringWithRange(
Range<String.Index>(prospectiveText.startIndex ..< prospectiveText.startIndex.advancedBy(maxLength))
)
selectedTextRange = selection
}
}
길이에 관계없이 문자열을 잘라내어 붙여 넣으려면 기능을 다음과 같이 변경하는 것이 좋습니다.
#define MAX_LENGTH 20
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSInteger insertDelta = string.length - range.length;
if (textField.text.length + insertDelta > MAX_LENGTH)
{
return NO; // the new string would be longer than MAX_LENGTH
}
else {
return YES;
}
}
스위프트 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
}
guard
?
스위프트 2.0 +
우선이 프로세스에 대한 클래스를 작성하십시오. 그것을 StringValidator.swift라고하자.
그런 다음 그 안에 다음 코드를 붙여 넣으십시오.
import Foundation
extension String {
func containsCharactersIn(matchCharacters: String) -> Bool {
let characterSet = NSCharacterSet(charactersInString: matchCharacters)
return self.rangeOfCharacterFromSet(characterSet) != nil
}
func containsOnlyCharactersIn(matchCharacters: String) -> Bool {
let disallowedCharacterSet = NSCharacterSet(charactersInString: matchCharacters).invertedSet
return self.rangeOfCharacterFromSet(disallowedCharacterSet) == nil
}
func doesNotContainCharactersIn(matchCharacters: String) -> Bool {
let characterSet = NSCharacterSet(charactersInString: matchCharacters)
return self.rangeOfCharacterFromSet(characterSet) == nil
}
func isNumeric() -> Bool
{
let scanner = NSScanner(string: self)
scanner.locale = NSLocale.currentLocale()
return scanner.scanDecimal(nil) && scanner.atEnd
}
}
이제 수업을 저장하십시오 .....
용법..
이제 viewController.swift 클래스로 이동하여 텍스트 필드의 콘센트를 ..
@IBOutlet weak var contactEntryTxtFld: UITextField! //First textfield
@IBOutlet weak var contactEntryTxtFld2: UITextField! //Second textfield
이제 텍스트 필드의 shouldChangeCharactersInRange 메소드로 이동하여 다음과 같이 사용하십시오.
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
if string.characters.count == 0 {
return true
}
let latestText = textField.text ?? ""
let checkAbleText = (latestText as NSString).stringByReplacingCharactersInRange(range, withString: string)
switch textField {
case contactEntryTxtFld:
return checkAbleText.containsOnlyCharactersIn("0123456789") && prospectiveText.characters.count <= 5
case contactEntryTxtFld2:
return checkAbleText.containsOnlyCharactersIn("0123456789") && prospectiveText.characters.count <= 5
default:
return true
}
}
텍스트 필드의 델리게이트 프로토콜 / 방법을 설정하는 것을 잊지 마십시오.
이것에 대해 설명하겠습니다 ... 다른 클래스에서 작성한 간단한 문자열 확장 프로세스를 사용하고 있습니다. 이제 확인 및 최대 값을 추가하여 필요한 다른 클래스에서 해당 확장 메소드를 호출하고 있습니다.
풍모...
종류 ...
containsOnlyCharactersIn // 문자 만 허용합니다.
containsCharactersIn // 문자 조합 허용
doesNotContainsCharactersIn // 문자를 허용하지 않습니다
도움이 되었기를 바랍니다 .. 감사합니다 ..
이 코드는 문자 제한보다 문자열을 붙여 넣을 때 제대로 작동합니다.
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
let str = (textView.text + text)
if str.characters.count <= 10 {
return true
}
textView.text = str.substring(to: str.index(str.startIndex, offsetBy: 10))
return false
}
투표 해 주셔서 감사합니다. :)
@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)
}
}
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
}
//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
}
}
이것은 UITextField에서 최대 길이를 처리하는 올바른 방법입니다. 리턴 키를 사용하여 텍스트 필드를 첫 번째 응답자로 사임하고 사용자가 한계에 도달하면 백 스페이스를 허용합니다.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
int MAX_LENGHT = 5;
if([string isEqualToString:@"\n"])
{
[textField resignFirstResponder];
return FALSE;
}
else if(textField.text.length > MAX_LENGHT-1)
{
if([string isEqualToString:@""] && range.length == 1)
{
return TRUE;
}
else
{
return FALSE;
}
}
else
{
return TRUE;
}
}
다른 답변은 사용자가 클립 보드에서 긴 문자열을 붙여 넣을 수있는 경우를 처리하지 않습니다. 긴 문자열을 붙여 넣으면 잘리지 만 표시되어야합니다. 대리인에게 이것을 사용하십시오.
static const NSUInteger maxNoOfCharacters = 5;
-(IBAction)textdidChange:(UITextField * )textField
{
NSString * text = textField.text;
if(text.length > maxNoOfCharacters)
{
text = [text substringWithRange:NSMakeRange(0, maxNoOfCharacters)];
textField.text = text;
}
// use 'text'
}
코드 한 줄로 줄였습니다 :)
텍스트 뷰의 델리게이트를 "self"로 설정 한 다음 <UITextViewDelegate>
.h에 .h에 다음 코드 를 추가하고 .m에 다음 코드 를 추가 하십시오. 최대 숫자를 원하는대로 숫자 "7"을 조정할 수 있습니다.
-(BOOL)textView:(UITextView *)a shouldChangeTextInRange:(NSRange)b replacementText:(NSString *)c {
return ((a.text.length+c.length<=7)+(c.length<1)+(b.length>=c.length)>0);
}
이 코드는 새 문자 입력, 문자 삭제, 문자 선택 후 입력 또는 삭제, 문자 선택 및 잘라 내기, 일반적인 붙여 넣기 및 문자 선택 및 붙여 넣기를 설명합니다.
끝난!
또는 비트 연산으로이 코드를 작성하는 또 다른 멋진 방법은 다음과 같습니다.
-(BOOL)textView:(UITextView *)a shouldChangeTextInRange:(NSRange)b replacementText:(NSString *)c {
return 0^((a.text.length+c.length<=7)+(c.length<1)+(b.length>=c.length));
}
속성 과 함께이 기능을 제공 하는 UITextField 서브 클래스 STATextField를 오픈 소스했습니다 maxCharacterLength
.
이제 얼마나 많은 문자를 원합니까?
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return (newLength > 25) ? NO : YES;
}
여기서이 코드를 사용하십시오. RESTRICTED_LENGTH는 텍스트 필드에 대해 제한하려는 길이입니다.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField == nameTF) {
int limit = RESTRICTED_LENGTH - 1;
return !([textField.text length]>limit && [string length] > range.length);
}
else
{
return YES;
}
return NO;
}
숫자 패드를 사용할 때 Swift에서 8 자 제한을 위해이 작업을 수행했습니다.
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
return !(textField.text?.characters.count == MAX_LENGTH && string != "")
}
삭제 버튼이 숫자 패드에서 작동하도록 문자열! = ""을 테스트해야했습니다. 그렇지 않으면 텍스트 필드의 최대 문자에 도달 한 후 문자를 삭제할 수 없습니다.
maxLength 속성을 추가하기 위해 UITextField Extension을 구현했습니다.
Xcode 6 IBInspectables를 기반으로하므로 인터페이스 빌더에서 maxLength 한계를 설정할 수 있습니다.
구현은 다음과 같습니다.
UITextField + MaxLength.h
#import <UIKit/UIKit.h>
@interface UITextField_MaxLength : UITextField<UITextFieldDelegate>
@property (nonatomic)IBInspectable int textMaxLength;
@end
UITextField + MaxLength.m
#import "UITextField+MaxLength.h"
@interface UITextField_MaxLength()
@property (nonatomic, assign) id <UITextFieldDelegate> superDelegate;
@end
@implementation UITextField_MaxLength
- (BOOL)textField:(UITextField *) textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
//validate the length, only if it's set to a non zero value
if (self.textMaxLength>0) {
if(range.length + range.location > textField.text.length)
return NO;
if (textField.text.length+string.length - range.length>self.textMaxLength) {
return NO;
}
}
//if length validation was passed, query the super class to see if the delegate method is implemented there
if (self.superDelegate && [self.superDelegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) {
return [self.superDelegate textField:textField shouldChangeCharactersInRange:range replacementString:string];
}
else{
//if the super class does not implement the delegate method, simply return YES as the length validation was passed
return YES;
}
}
- (void)setDelegate:(id<UITextFieldDelegate>)delegate {
if (delegate == self)
return;
self.superDelegate = delegate;
[super setDelegate:self];
}
//forward all non overriden delegate methods
- (id)forwardingTargetForSelector:(SEL)aSelector {
if ([self.superDelegate respondsToSelector:aSelector])
return self.superDelegate;
return [super forwardingTargetForSelector:aSelector];
}
- (BOOL)respondsToSelector:(SEL)aSelector {
if ([self.superDelegate respondsToSelector:aSelector])
return YES;
return [super respondsToSelector:aSelector];
}
@end