Setting a text box’s maximum length, the Visual Studio way
Here’s how you set the maximum number of characters than can be entered into a text box when developing C# and VB applications in Microsoft Visual Studio:
There’s the GUI builder way…
- Select the text box.
- Set its
MaxLength
property in the Properties pane.
…and there’s the code way:
myTextBox.maxLength = 3 // or whatever length you like
Setting a text field’s maximum length, the out-of-the-box Xcode way
Here’s how you set the maximum number of characters than can be entered into a text field when developing Objective-C and Swift applications in Xcode:
There isn’t a GUI builder way — just a code way, and it’s a little more work than it needs to be. The typical steps are:
- Make the containing view controller a text field delegate (i.e. make it adopt the
UITextFieldDelegate
protocol) so that it receives messages from all the text fields it contains. - Implement the
textfield(_:shouldChangeCharactersInRange:replacementString)
method in order to intercept changes to any of the view’s text fields before they’re finalized. This involves:- Identifying the text field whose contents were changed, usually with an
if
orswitch
statement. If the text field is one whose text we want to limit to a certain length, then:- If the change in contents will result in the text not exceeding that length, simply return
true
. - If the change in contents will result in the text exceeding that length, return
false
. You may want to take some additional action: for example, if the user tries to paste in more text you want to allow in the text field, you may want to allow a “partial paste” — pasting in the first n characters that will fit in the remaining space — and not reject the pasted text outright.
- If the change in contents will result in the text not exceeding that length, simply return
- Identifying the text field whose contents were changed, usually with an
If you’re curious, I covered this in an earlier article, How to program an iOS text field that takes only numeric input or specific characters with a maximum length.
That’s a lot of work. Isn’t there a way we can get a “max length” property for text fields, like the .NET people?
The screen shot above (if you ignore my text annotations) isn’t Photoshoppery on my part. That’s a screen shot of my Xcode showing a selected text field and a corresponding Max Length property editor in the Attributes panel. With just a little coding in a single file, you too can your iOS text fields these goodies that .NET developers have had for ages and set the maximum length of text in a text field in both these ways:
- The GUI builder way, and
- With a single line of code.
Setting a text field’s maximum length, the improved Xcode way
Start a new project by doing the standard File → New → Project… dance to create a new Single View Application. Open Main.storyboard and place a single text field on the view:
Select the text field and switch to the Attributes Inspector (the inspector panel with the icon). The Attributes Inspector lets you edit all sorts of text field properties, but not the maximum length…yet.
Use File → New → File… to create a new Swift File. Give it the name TextFieldMaxLengths.swift, and once you’ve created it, enter the following code into it:
import UIKit extension UITextField { @IBInspectable var maxLength: Int { get { return 5 } set { } } }
Switch back to Main.storyboard, select the text field and look at the Attributes Inspector. You may notice that something’s changed:
All we did was create an extension for the UITextField
class to give it an extra Int
property named maxLength
. Marking this property with the @IBInspectable
keyword makes the property available to the Attributes Inspector (hence the name — the property can be inspected in Interface Builder).
Now that we’ve added a property to UITextField
and made it inspectable within Interface Builder, it’s time to make the property do something.
If you’re using Swift 2.x, update the code in TextFieldMaxLengths.swift to the code below (keep scrolling if you’re using Swift 3):
// Swift 2.x version // This will NOT work with Swift 3! // ================================ import UIKit // 1 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 } }
If you’re using Swift 3, update the code in TextFieldMaxLengths.swift to the code below:
// Swift 3 version // This will NOT work with Swift 2.x! // ================================== import UIKit // 1 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), for: UIControlEvents.editingChanged ) } } func limitLength(textField: UITextField) { // 6 guard let prospectiveText = textField.text, prospectiveText.characters.count > maxLength else { return } let selection = selectedTextRange // 7 let maxCharIndex = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength) text = prospectiveText.substring(to: maxCharIndex) selectedTextRange = selection } }
Here are my annotations that match the numbered comments in the code:
- There are two big things going on in this single line of code, which declares and initializes
maxLengths
, a dictionary that stores the maximum lengths of text fields:- First, there’s the
private
declaration. In many programming languages,private
means “accessible only inside the class”, but in Swift,private
means “accessible only inside the source file where they’re defined”. Any code inside TextFieldMaxLengths.swift has access tomaxLengths
, and any code outside TextFieldMaxLengths.swift does not. By puttingmaxLengths
in the same file as ourUITextField
extension, we get a place where we can store the maximum lengths of text fields (remember: extensions can only add methods, not properties), and by making itprivate
, we keep other code from messing with it. - Then there’s the matter of what to use as the key for the
maxLengths
dictionary. Swift lets you use anything that conforms to theHashable
protocol as a dictionary key, andUITextField
does just that. It makes sense to use the text fields themselves as the keys to the values for their maximum lengths.
- First, there’s the
- Swift
extension
s let you add new functionality to existingclass
es,struct
s,enum
erations, andprotocol
s. We’re using anextension
toUITextField
to add two things:maxLength
, a property that lets the programmer set and get the maximum length of a text field, andlimitLength
, a method called whenever the contents of a text field are changed, and limits the number of characters in that text field.
- By marking the
maxLength
property with@IBInspectable
, we make it available to Interface Builder, which then provides an editor for its value in the Attributes Inspector. - Get to know and love the
guard
statement and the “early return” style of programming; you’re going to see a lot of it in a lot of Swift coding. Here, we’re usingguard
to filter out cases where no maximum length has been defined for the text field, in which case, we simply return the theoretical maximum string size. - We use
addTarget
inmaxLength
‘s setter to ensure that if a text field is assigned a maximum length, thelimitLength
method is called whenever the text field’s contents change. - Another
guard
statement. Any case that gets past it is one where the text about to go into the text field is longer than the maximum length. - Cocoa sometimes likes to make things complicated. This line is the Cocoa way of saying “put the first
maxLength
characters ofprospectiveText
intotext
“. If you’re going to be playing with substrings, you need to get comfortable withRange
s and intervals.
If you include TextFieldMaxLengths.swift in any of your iOS projects, all text fields will have a maxLength property that you can set either GUI builder style in Interface Builder or in code, using myTextField.maxLength = n
syntax, just like the .NET people do.
Happy text field coding!
“Text2”: A sample project showing Visual Studio-style text field maximum lengths in action
If you’d like to try out the code from this article, I’ve create a project — unimaginatively named Text2 and pictured above— that shows our UITextField
extension in action. It’s a quick-and-dirty single view app that presents 4 text fields:
- A text field without a set maximum length.
- A text field with a 1-character maximum length, with the Max Length property set in Interface Builder.
- A text field with a 5-character maximum length, with the
maxLength
property set in code (in the view controller’sviewDidLoad
method). - A text field with a 10-character maximum length, with the Max Length property set in Interface Builder.
Give it a try, learn what makes it tick, and use it as a jumping-off point for your own projects!
You can download the project files for this article (27KB zipped) here.
This code was derived from a Swift 1.2 solution posted by Frouo in Stack Overflow. I annotated it, and updated it so that it would be compatible with both Swift 2 and 3.
13 replies on “iOS programming trick: How to use Xcode to set a text field’s maximum length, Visual Studio-style [Updated for Swift 3]”
[…] For more details, you should take a look at that article, iOS programming trick: How to use Xcode to set a text field’s maximum length, Visual Studio-style. […]
[…] Here’s a neat trick that might have never occurred to you (it didn’t to us, anyways). […]
I found your excellent site while looking for a solution to limiting the number of characters in a text field.
This is exactly what i was looking for – works great in Xcode 7.x, but errors out in Xcode 8 beta 6.
There were 4 errors , and Xcode was able to correct all of them except this last one.
Could you point me in the right direction to solve this?
Thanks!
The Elder Noob
!Error:
Value of type ‘String’ has no member ‘substringWithRange’
text = prospectiveText.substringWithRange(
Range(prospectiveText.startIndex ..< prospectiveText.startIndex.advancedBy(maxLength)
Hey, Steve!
I’ve updated the article so that there are two versions of TextFieldMaxLengths.Swift — one for Swift 2.x and one for Swift 3.
Joey,
Thank you for posting the Swift 3 code.
it works perfectly!
The Elder Noob
Espectacular. Thank you very much. Great code.
I am newbie to swift programming
Wonderfully.. working fine in swift3.0..
Thank you for the help.
Can i do anyother attributes like this.
Hi
I have used your code in a project I am developing so a big thank you, however, swift 4 is complaining about the depreciation
again, will you be producing an update or should I find myself a work around?
Thanks
Steve
Man, thank you very much, you are amazing!!
Swift 4 tip:
Replace last two lines of the func limitLength with:
text = String(prospectiveText[..<maxCharIndex])
selectedTextRange = selection
Great ! Thanks for this excellent code. Works perfectly with swift 4 , with Carl’s modification
Hi, I loved this article and putting the maximum. I was wondering if you already have or could make an article about making an @IBInspectable minimum character option? I was thinking of using this for a password, for example, where they have to at least have 8 characters. I tried to copy in the maximum text and change words and what they do to make it work for a minimum, but it doesn’t really work. Could you please direct me to that article or could you please make one?
[…] 如果您还有其他问题,请查看此链接:http : //www.globalnerdy.com/2016/05/18/ios-programming-trick-how-to-use-xcode-to-set-a-text-fields -最大长度的视觉工作室风格/ […]