UITextView
character limit
iOS development
Swift programming
text input restrictions

Limit number of characters in uitextview

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

To limit the number of characters in a UITextView, intercept edits through the delegate and decide whether the proposed change should be accepted. The key detail is that you must compute the resulting text after the edit, not just check the current text length.

Use shouldChangeTextIn in the Delegate

The standard place to enforce a limit is the delegate method textView(_:shouldChangeTextIn:replacementText:).

swift
1import UIKit
2
3final class ViewController: UIViewController, UITextViewDelegate {
4    @IBOutlet weak var textView: UITextView!
5    let limit = 140
6
7    override func viewDidLoad() {
8        super.viewDidLoad()
9        textView.delegate = self
10    }
11
12    func textView(_ textView: UITextView,
13                  shouldChangeTextIn range: NSRange,
14                  replacementText text: String) -> Bool {
15        guard let current = textView.text,
16              let stringRange = Range(range, in: current) else {
17            return false
18        }
19
20        let updated = current.replacingCharacters(in: stringRange, with: text)
21        return updated.count <= limit
22    }
23}

This handles typing, deletion, and replacement in one place.

Why Range Conversion Matters

UITextView gives you an NSRange, but Swift strings are Unicode-aware. Converting the range properly is important, especially when the text contains emoji or other multi-scalar characters.

That is why the Range(range, in: current) conversion is safer than trying to slice by integer offsets manually.

Update a Counter Label at the Same Time

In real apps, users usually benefit from a remaining-character counter.

swift
1func textViewDidChange(_ textView: UITextView) {
2    let remaining = limit - textView.text.count
3    counterLabel.text = "\(remaining)"
4}

The delegate check enforces the rule, and the counter makes the rule visible.

Be Careful With Pasting and Marked Text

Character limits are not only about keyboard typing. Pasting large text can exceed the limit in one action, so the delegate check must handle replacement text of any size.

If you support complex input methods, also remember that temporary marked text during composition can make editing behavior more subtle. Test with real keyboards and languages, not only with simple Latin typing.

If You Need Truncation Instead of Rejection

Some apps prefer to accept the paste but truncate the final text.

swift
1func textViewDidChange(_ textView: UITextView) {
2    if textView.text.count > limit {
3        textView.text = String(textView.text.prefix(limit))
4    }
5}

This is a different user experience from rejecting the change upfront. Use it only if that behavior is intentional.

Decide Whether Hard Blocking or Soft Feedback Is Better

Some apps should block extra input immediately. Others should let the user keep editing temporarily and show a counter or validation message. The technical implementation is different, but the real decision is product behavior rather than delegate syntax alone.

Keep the UX Consistent With Validation Elsewhere

If the same field is also validated on the backend, make sure the frontend character limit matches the server rule. Mismatched limits create confusing bugs where the UI accepts text that the API later rejects, or vice versa.

Test With Real Copy and Paste Behavior

Typing one character at a time is the easy case. Paste operations are where many length-limit implementations show their real behavior, so they should be part of the normal test path.

Common Pitfalls

The biggest mistake is checking only textView.text.count before the edit instead of calculating the post-edit result.

Another issue is forgetting about paste operations, which can add many characters at once.

A third problem is mishandling Unicode by working with raw integer indexes instead of converting the range safely.

Summary

  • Use textView(_:shouldChangeTextIn:replacementText:) to enforce a character limit.
  • Compute the resulting text after the proposed change, not just the current length.
  • Convert NSRange safely into a Swift string range.
  • Test with paste operations and non-trivial Unicode input.
  • Pair the limit with a visible counter when user experience matters.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.