NSTextAttachment
Recently I had a relatively simple design to implement, which looked something like this:
Initially, I thought this would be a simple stack view, with a label and a stack view of a label and image view, only to realize soon after that this will be hard to get right when the main label has 4 words and is broken in 2 lines for example. And in a situation where the main label has 3 words, the width will be enough to make rating label and star image view look like they are far away from the last word in the main label. This seemed like a really simple thing to implement, so I thought there has to be a right, uncomplicated way to do things like this. According to this design at least, rating label and star image will always be at the end of the main label.
Attributed string came to my mind, so after digging & researching a bit, I found this beautiful class called NSTextAttachment. First introduced in iOS 7 (though it took a while, macOS had this since 2001), this class allows you to easily embed images into attributed strings, without worrying about any Auto Layout rules, it just gets drawn right along with the text.
Get Nemanja Vlahovic’s stories in your inbox
Join Medium for free to get updates from this writer.
Here is an example to get you started:
// create text attributes for first string
let locationTextAttributes: [NSAttributedStringKey: Any] = [.strokeColor : UIColor.black,.font : UIFont(name: “Helvetica-Bold”, size: 28.0)!]// create NSMutableAttributedString that we'll append string & image tolet a = NSMutableAttributedString(“Temakerio", attributes:locationTextAttributes)// create text attributes for second stringlet ratingTextAttributes: [NSAttributedStringKey: Any] = [.strokeColor : UIColor.black,.font : UIFont(name: “Helvetica”, size: 10.35)!]// create another NSAttributedStringlet b = NSAttributedString(“4,5", attributes:ratingTextAttributes)// blend two strings into onea.append(b)// create NSTextAttachment and add image to itlet imageAttachment = NSTextAttachment()imageAttachment.image = imageLiteral(resourceName: “starBlack”)// create NSAttributedString with the above created NSTextAttachment using the attachment initializerlet imageString = NSAttributedString(attachment: imageAttachment)// append everything to initially created attributed stringa.append(imageString)
I hope you find this useful. I guess this is a easily overlooked class, but it made my life so much easier in this situation.





