How to Restrict Emoji Input and Enforce Character Length in Swift (with UITextField & UITextView)
๐ Overview
When building iOS apps, you often want to:
- ๐ซ Prevent users from typing emoji characters
- โ
Allow only specific inputs like numbers,
#
,*
- ๐ Count string length accurately (
UTF-8
orUTF-16
) - โจ๏ธ Enforce ASCII-capable keyboards only
In this blog, youโll learn how to do all of that in a clean and reusable way using String
extensions, UITextFieldDelegate
, and UITextViewDelegate
.
โ Goals
- โ Disallow emojis in
UITextField
andUITextView
- โ
Allow special characters like
0-9
,#
,*
- ๐ง Detect input length by
utf8.count
orutf16.count
- โจ๏ธ Force ASCII-capable keyboard
๐ก 1. Create String
Extension
import Foundation
extension String {
var utf8Length: Int {
return self.utf8.count
}
var utf16Length: Int {
return self.utf16.count
}
var hasEmoji: Bool {
return self.unicodeScalars.contains { scalar in
switch scalar.value {
case 0x30...0x39, // '0' to '9' should not be considered emoji i.e. number
0x0023, // '#'
0x002A: // '*'
return false
case 0x1F600...0x1F64F, // Emoticons (e.g., ๐๐๐๐๐)
0x1F300...0x1F5FF, // Misc Symbols and Pictographs (e.g., ๐ธ๐๐ก๐ฟ๐)
0x1F680...0x1F6FF, // Transport and Map Symbols (e.g., ๐โ๏ธ๐๐โต๏ธ)
0x1F1E6...0x1F1FF, // Regional Indicator Symbols (used for country flags ๐ฎ๐ณ๐บ๐ธ)
0x2600...0x26FF, // Misc Symbols (e.g., โ๏ธโ๏ธโ๏ธโน๏ธโป๏ธโ ๏ธ)
0x2700...0x27BF, // Dingbats (e.g., โ๏ธโ๏ธโ๏ธโ ๏ธโ๏ธ)
0x1F900...0x1F9FF, // Supplemental Symbols and Pictographs (e.g., ๐ค๐ฆ๐ฅ๐ง ๐ฆท)
0x1F018...0x1F270, // Various emoji-like symbols (e.g., ๐๏ธ๐๐๐)
0x238C...0x2454, // Misc technical symbols (e.g., โฐโณโญ๏ธโฎ๏ธโธ๏ธ)
0x20D0...0x20FF: // Combining Diacritical Marks for Symbols (variation selectors like โ ๏ธ)
return true
default:
return scalar.properties.isEmoji // Fallback check for any other emoji
}
}
}
}
๐ก 2. Enforce Emoji Restriction in UITextField & UITextView
extension ViewController: UITextViewDelegate, UITextFieldDelegate {
func textView(_ textView: UITextView,
shouldChangeTextIn range: NSRange,
replacementText text: String) -> Bool {
return !text.hasEmoji
}
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
// Restrict emojis in specific text field
if textField == specificTextField {
return !string.hasEmoji
}
return true
}
}
๐ก 3. Force ASCII Keyboard Type
override func viewDidLoad() {
super.viewDidLoad()
specificTextField.delegate = self
abcTextView.delegate = self
specificTextField.keyboardType = .asciiCapable
abcTextView.keyboardType = .asciiCapable
}
๐ก 4. Dismiss Keyboard on Tap Outside (Optional UX Tip)
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
๐งช Test It Out
debugPrint("Hello".hasEmoji) // false
debugPrint("123".hasEmoji) // false
debugPrint("speical โ๏ธ".hasEmoji) // true
debugPrint("Hello ๐".hasEmoji) // true
โจ Bonus: Length Validation Example
if inviteNameTextField.text?.utf16Length ?? 0 > 160 {
print("Text exceeds UTF-16 byte limit")
}
๐ Conclusion
With a few lines of reusable code:
- You protect your inputs from emojis
- Maintain database-safe character limits
- Ensure cleaner UX and backend consistency
This is ideal for forms, signups, chat inputs, payment fields, or any strict validation flow in your app.
๐ Summary Checklist
โ
Emoji check in String
extension
โ
Limit text input using UITextFieldDelegate
& UITextViewDelegate
โ
Enforce .asciiCapable
keyboard
โ
Optional: Limit text length using .utf16Length
Appreciate you going through this โ if it helped in any way, feel free to like or share!