Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to get UTF8 encoded byte count of a string given a particular NSRange?

To get the UTF8-encoded byte count of a string, I would simply do the following.

let str = "it's 🌮 time"
let totalUTF8EncodedBytes = str.utf8.count

print(totalUTF8EncodedBytes) // 14

However, if I’m given an NSRange of this string, how can I get the UTF8-encoded byte count of that range?

To add some context, I want to limit the characters entered into a text view both with a character limit and a byte limit. The character limit is done. The byte limit also technically works but when pasting a block of text that should fit within the byte limit over an existing range of text, it returns false when it should return true since it doesn’t account for the range.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if let charLimit = characterLimit {
        let currentChars = textView.text.count
        let newChars = text.count - range.length
        let totalChars = currentChars + newChars
        return totalChars <= charLimit
    }
    
    if let byteLimit = utf8EncodedByteLimit {
        let currentBytes = textView.text.utf8.count
        let newBytes = text.utf8.count
        let totalBytes = currentBytes + newBytes
        return totalBytes <= byteLimit
    }
    return false
}

>Solution :

All you need to do is get the substring from the range:

let subStr = (str as NSString).substring(with: range)

Then you can get the utf8.count of subStr, or do it all on one line:

let subCount = (str as NSString).substring(with: range).utf8.count

But for your shouldChangeTextIn, you can simply do the following:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    let newStr = (textView.text! as NSString).replacingCharacters(in: range, with: text)
    if let charLimit = characterLimit {
        return newStr.count <= charLimit
    }

    if let byteLimit = utf8EncodedByteLimit {
        return newStr.utf8.count <= byteLimit
    }

    return false
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading