Strip whitespace in a UITextRange - ios

I am working with a UITextView and am trying to programmatically change the selection so that it contains no leading or trailing whitespace, akin to String.trimmingCharacters(in: .whitespace).
My approach would be to locate the outermost non-whitespace characters within the region, and then have the appropriate checks to make sure that the region is not empty or reversed. (But I have no idea how to go about this.)
textView.selectedTextRange = textView.textRange(from: 'position of first non-whitespace character after textRange.start',
to: 'position of first non-whitespace character before textRange.end')
Or perhaps there is a better approach, maybe using the UITextView’s tokenizer? In fact, the original selection range that I am trying to strip is acquired by
textView.tokenizer.rangeEnclosingPosition(position, with: .paragraph, inDirection: UITextLayoutDirection.left.rawValue)
however I don't want the trailing newline engulfed by UITextGranularity.paragraph to be included in the range.

Related

How to achieve UILabel line breaks only on a specific separator character?

I have a string which has a separator character between words (Words with spaces) eg.
"Male • 89 • Senior Citizen • Side Lower Berth • Non Veg • Bedroll"
So "•" is separator here. Now while assigning it to a multiline label I want line breaks only on this separator. Eg. I don't want line breaks in between "Side Lower Berth" so that some part of it rendered in the first line and remaining one in next line. It should draw it next line only by making the decision based on the defined separator "•" here.
Try replacing all of your ordinary spaces with nonbreaking spaces, except in the places where you want to allow that break the line. (So leave an ordinary space after each bullet)
What if you jump lines when • appears? If you wanna try :
yourString.replacingOccurrences(of: "•", with: "\n")
I don't know if that's what you want, if not, sorry.

Fragile Space – opposite of non-breaking space

Under iOS I'm wondering if there is a kind of "extra fragile" space that I could put in to a string.
If I display it in a UILabel (or other control), and the text needs to be split over >1 line, then the layout would try to split on a a fragile space if it possibly can.
Eg, if <> is a fragile space symbol, then the string "All on one line if possible<>but this on another line if needed." would display as:
All on one line if possible
but this on another line if needed.
… assuming that there wasn't room for the whole string on one line.
Or perhaps the concept is more a "Newline here if you need to".
Maybe something with ranges in NSAttributedString that can describe where breaking should be preferred? Or some other way to specify this to a label?

In a UILabel, is it possible to force a line NOT to break in a certain place

I have a UILabel that is supposed to be two lines long. The text is localized into French and English.
I'm setting the attributedText property of the label. The text is constructed from three appended strings, say textFragment1, textFragment2 and textFragment3. The middle string is actually an image created with an NSTextAttachment.
I want to make sure that textFragment2 and textFragment3 are on the same line. The first string may or may not wrap depending on how long it is. The problem is that my French text is currently fairly short, so the line is wrapping after textFragment2.
I have fixed this temporarily by adding a line break symbol in the localized French text for textFragment1. I don't really love this solution though. I was wondering if there is a way to treat textFragment2 and textFragment3 so that they will always be together on the same line.
You could use a non-breaking space (\u00a0) to join textFragment2 and textFragment3. This character looks just like a normal space—i.e. it results in the same amount of whitespace—but line breaking will not take place on either side of it.
You could also use a zero-width space (\u2060). Using this character will not result in any whitespace, but it will still prevent line breaking on either side. This is what you want if you don’t want any space between textFragment2 and textFragment3 but you still want to prevent line breaking there. (It’s also useful if you have a word with a hyphen in the middle of it but you want to prevent the line from being broken after the hyphen.)
You can read more about these kinds of characters on Wikipedia.

Setting NSLineBreakByTruncatingHead has no effect

I have the following lines of code:
textView.textContainer.maximumNumberOfLines = 10;
textView.textContainer.lineBreakMode = NSLineBreakByTruncatingHead;
[textView setText:#"1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11"];
No matter what I set the lineBreakMode to, the output always excludes the 11, but includes the 1. I need to truncate the start of the string, not the end. Any ideas on why this isn't working?
That’s not what the line break mode does. If an individual line is wider than will fit in the text view, that mode should cause it to get truncated at the head rather than wrapping to an additional line, but it won’t cause the text view to change which lines it displays.
To get the effect you’re after, you’ll have to modify the string yourself. If it’s formatted the way your test string is (with explicit newlines) that’s relatively easy—-rangeOfString:options:range: will let you search backwards along the string until you find the start of the Nth line you want to keep—but if you’re relying on word wrapping, then you’ll have to use -boundingRectWithSize:options:attributes: and keep chopping words off the beginning until it fits within the size you need.

RichEdit's ITextRange: Determine if a user's cursor is in a word?

I'm using ITextRange from a RichEdit control. I want to determine if a user's cursor is touching a word.
The problem is that calling iTextRange.expand(tomWord) will include tailing spaces:
Brackets indicate the range:
Before:
weas[]el .
After:
[weasel ].
My original plan was to expand the range, and check if it contained the cursor. But the user's cursor could be two spaces after "weasel", and the range will still expand to contain it. So what else can I do?
I can recall facing a similar problem: that is, how to select a word without selecting any trailing space. I think that code like this C++
textRange->StartOf(tomWord,tomMove,NULL);
textRange->MoveEnd(tomWord,1,NULL);
should give you the right selection, so that you can then test if the caret is in the selection.

Resources