Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting an image imbedded in an NSAttributedString (via NSTextAttachment) to be treated as a single character, so that it doesn't break lines?

I'm embedding an image in an NSAttributedString, and I want iOS to treat it as a character that is a part of the word before it, so that it doesn't get broken onto its own line. I read somewhere that is supposed to be the default behavior, but for the life of me I can't get it to work. Here's my code (I'm the inserting this attributed string as the title of a button):

    var title = "This is an example string. Test testtt"
    let titleTextString = NSMutableAttributedString(string: title)

    let imageAttachment =  NSTextAttachment()
    imageAttachment.image = UIImage(named:"myIcon")
    imageAttachment.bounds = CGRect(x: 0, y: 1.0, width: 14, height: 6)
    let imageAttachmentString = NSMutableAttributedString(attachment: imageAttachment)


    titleTextString.append(imageAttachmentString)
    button.setAttributedTitle(titleTextString, for: .normal)

Here's an image of what it looks like:

enter image description here

As you can see, there is no whitespace at the end of the string. I am trying to get the label to consider the text attachment a normal non-whitespace character, and thus part of the word "testtt", which would then cause the "testtt" to be word-wrapped (words are otherwise correctly word-wrapped, and I've set word wrapping on both the label and in the paragraph style of the NSAttributedString).

Complicating this matter is that I found the existence of a non-breaking which solve the problem, but forces other parts of the string to be unnecessarily broken. If I append a non-breaking space to the end of the string:

var title = "This is an example string. Test testtt" + "\u{A0}"

I then get the correct breaking behavior, but for some reason the previous word is also unnecessarily broken:

enter image description here

Does anyone have any idea how to get this to behavior correctly (i.e., count the image as any other letter, rather than whitespace?)

like image 534
milohoffman Avatar asked Oct 15 '22 15:10

milohoffman


1 Answers

You can accomplish that by adding a zero-width non-breaking space: \u{FEFF} to the end of your original string.

var title = "This is an example string. Test testtt\u{FEFF}"
let titleTextString = NSMutableAttributedString(string: title)

let imageAttachment =  NSTextAttachment()
imageAttachment.image = UIImage(named:"myIcon")
imageAttachment.bounds = CGRect(x: 0, y: 1.0, width: 14, height: 6)
let imageAttachmentString = NSMutableAttributedString(attachment: imageAttachment)


titleTextString.append(imageAttachmentString)
button.setAttributedTitle(titleTextString, for: .normal)

Credit to this SO question+answer In a UILabel, is it possible to force a line NOT to break in a certain place

EDIT:

To answer your question about wrong word wrapped. You can find the answer here. It's a new behavior for word wrapping introduced by Apple.

like image 56
Gustavo Conde Avatar answered Nov 15 '22 06:11

Gustavo Conde