Unfortunately, there is no property for UITextField that allows controlling the maximum length of text entered into it. Instead, this behavior can, for instance, be achieved by using an appropriate delegate method of the UITextFieldDelegate.

This approach might be handy if it is needed for only few text fields, which have the same maximum length for their texts. However, it can get confusing quickly because of two aspects. Firstly, if you need to add the same delegate method to multiple controller classes, you have redundant code which is always a bad thing. Secondly, if you need different maximum lengths for multiple text fields, you end up with a switch case mess in the delegate method.

Instead, I want to be able setting the maximum length of the text in the storyboard directly in Xcode. This would allow quickly setting the max length for multiple fields in different view controllers. Therefore, I have come up with the following approach. As there is no built-in max length functionality for UITextFields, I employ the ‘User Defined Runtime Attributes’ in Xcode. After selecting the text field for which I want to set the maximum length, I enter the following information in the User Defined Runtime Attributes:
XcodeScreenSnapz012

The goal of the example above is limiting the max length of the text of the selected text field to ten letters. However, if the storyboard would be loaded now in the app, it would crash as there is no such property called maxLength on an UITextField. To add this property to all UITextFields in the app, I add the following category to the project:

UITextField+RuntimeExtension.h

1
2
3
4
5
#import <UIKit/UIKit.h>
 
@interface UITextField (RuntimeExtension)
@property(nonatomic, assign) NSNumber* maxLength;
@end

UITextField+RuntimeExtension.m

1
2
3
4
5
6
7
8
9
10
11
12
13
#import <objc/runtime.h>
 
#import "UITextField+RuntimeExtension.h"
 
static void *MaxLengthKey;
@implementation UITextField (RuntimeExtension)
-(void)setMaxLength:(NSNumber *)maxLength{
    objc_setAssociatedObject(self, &MaxLengthKey, maxLength, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSNumber*)maxLength{
    return objc_getAssociatedObject(self, &MaxLengthKey);
}
@end

This code adds the property maxLength to all UITextFields in the project. The storyboard can now be loaded and executed safely without crashing. However, until now, this functionality does not do anything.

To make the magic happen and control the max length, we need to add the appropriate delegate method to the UITextField’s delegate. As UITextFields are usually added to a UIViewController, I have created the following category implementing the appropriate method from UITextFieldDelegate in a category of UIViewController:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#import "UIViewController+TextFieldDelegate.h"
#import "UITextField+RuntimeExtension.h"
 
@implementation UIViewController (TextFieldDelegate)
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    BOOL shouldChange = YES;
 
    if(textField.maxLength){
        // 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;
            shouldChange = (newLength > [textField.maxLength integerValue]) ? NO : YES;
        if(!shouldChange){
            return shouldChange;
        }
    }
     return shouldChange;
}
@end

This method basically looks if the maxLength property is set on the text field and prevents that the text gets too long. Beware that you have to set the UIViewController in which the text field is used as the text field’s delegate (which Xcode afaik sets by default).

That’s it. Download the categories here and simply drop them into your project. Now you can set max length of a text field easily in Xcode without writing a single line of code. Simply add maxLength as user defined runtime attribute as displayed above. It goes without saying that you can also control the text field’s max length by setting it in the code. You are not forced to use a storyboard. All you have to do for this, is importing UITextField+RuntimeExtension.h in the view controller where you want to set maxLength.

For your convenience, you will find additional runtime properties in the downloaded categories that you can set for a text field. If isDecimalField is set to YES, you can only enter digits into the text field. If isEMailAddress is set, you have to enter a mail address with a valid mail structure. Endless possibilities :)

Published by Johannes Luderschmidt

About this blog