Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String containing certain characters causing UITextView to wrap too soon

Context

I am trying to enter a bunch of random text into a text view and character wrap it so the box is completely full of the symbols. It seems as though the text view is trying to be smart about when it wraps based upon certain characters in the text. I have narrowed down the list of characters that causes the text view wrap incorrectly to the following:

] } ) . > / +

The rest of the characters that could be displayed are:

[ < { ( # @ = * ~

The following code run in a Playground will result in a UITextView that has wrapping before the last character in the line.

import UIKit

func generateRandomText() -> NSAttributedString {
    let characterLimit = 9500
    let segmentSize = 500
    // problem characters
    // ] } ) . > / +
    let characterOptions = ["[","<","{","(","#","@","=","*","~","+","]","}",")",".",">","/"]
    let codeString = NSMutableAttributedString.init(string: "")

    while codeString.string.characters.count < segmentSize {
        let addition = NSAttributedString.init(string: characterOptions[Int(arc4random_uniform(16))], attributes: [NSForegroundColorAttributeName : UIColor.whiteColor()])
        codeString.appendAttributedString(addition)
    }

    while codeString.string.characters.count < characterLimit {
        codeString.appendAttributedString(codeString)
    }

    return codeString
}

let textView = UITextView.init(frame: CGRectMake(0, 0, 700, 700))
textView.textContainer.lineBreakMode = .ByCharWrapping

let codeFont = UIFont.init(name: "Menlo", size: 12)
textView.font = codeFont
textView.backgroundColor = UIColor.blackColor()
textView.attributedText = generateRandomText()

Result:

enter image description here

However, the same code without the problem characters produces the results I am looking for.

import UIKit    

func generateRandomText() -> NSAttributedString {
    let characterLimit = 9500
    let segmentSize = 500
    // problem characters
    // ] } ) . > / +
    let characterOptions = ["[","<","{","(","#","@","=","*","~"]
    let codeString = NSMutableAttributedString.init(string: "")

    while codeString.string.characters.count < segmentSize {
        let addition = NSAttributedString.init(string: characterOptions[Int(arc4random_uniform(9))], attributes: [NSForegroundColorAttributeName : UIColor.whiteColor()])
        codeString.appendAttributedString(addition)
    }

    while codeString.string.characters.count < characterLimit {
        codeString.appendAttributedString(codeString)
    }

    return codeString
}

let textView = UITextView.init(frame: CGRectMake(0, 0, 700, 700))
textView.textContainer.lineBreakMode = .ByCharWrapping

let codeFont = UIFont.init(name: "Menlo", size: 12)
textView.font = codeFont
textView.backgroundColor = UIColor.blackColor()
textView.attributedText = generateRandomText()

Result:

enter image description here

Question

What would cause the text view to wrap when a string contains certain characters?

like image 619
Addison Avatar asked Apr 21 '26 18:04

Addison


1 Answers

Those certain characters are the ones the system uses to define word boundaries, to be used for word wrapping.

Calling

textView.textContainer.lineBreakMode = .ByCharWrapping

has no effect since UITextView doesn't support character wrapping.


Docs:

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Strings/Articles/stringsParagraphBreaks.html

http://www.unicode.org/reports/tr29/#Word_Boundaries

Do note that there are complicated rules to define word boundaries. For example, "1.0" is considered one word but "a.1" is considered two.

Also, it's possible that the Unicode specification is not followed exactly.

like image 50
Code Avatar answered Apr 23 '26 09:04

Code