Archimboldi's Blog

How to display and arrange images and text in UITextView?

UITextView has an instance property attributedText: NSAttributedString!, NSAttributedString can be initialized with NSTextAttachment, NSTextAttachment can hold images.
This is a sample of Swift 3 code.

view.backgroundColor = UIColor.yellow
textView.frame = CGRect.init(x: view.bounds.origin.x, y: view.bounds.origin.y + 44, width: view.bounds.size.width, height: view.bounds.height - 44 * 2)
textView.backgroundColor = UIColor.white
textView.isEditable = false

// UITextView.attributedText defaults to an entire line before appeared, so the position of the text/image will depend on the previous text/image, 
// and it is difficult to calculate and arrange the text/image.
// If the text/image is in a separate line, you should insert a line break before the text/image, the text/image is calculated and arranged simply and easily.
let lineBreak = NSAttributedString.init(string: "\n")
let textMutableAttributedString = NSMutableAttributedString.init()

let titleText = "Wow"
let titleParagraphStyle = NSMutableParagraphStyle.init()
titleParagraphStyle.alignment = .center
let titleAttributes: [String : Any] = [NSFontAttributeName : UIFont.systemFont(ofSize: 21, weight: UIFontWeightMedium), NSParagraphStyleAttributeName : titleParagraphStyle]
let titleAttributedString = NSMutableAttributedString.init(string: titleText, attributes: titleAttributes)

// The image will be centered, so that the simple way to calculate is to start a new line.
// In a new line, the origin of the imageAttachment in the lower left corner.
let imageAttachment = NSTextAttachment.init()
imageAttachment.image = UIImage.init(named: "Lenna")
// You can set image bounds, be attention on origin.y
// imageAttachment.bounds = CGRect.init(x: 0, y: -8, width: (imageAttachment.image?.size.width)!, height: (imageAttachment.image?.size.height)!)
let imageAttributedString = NSAttributedString.init(attachment: imageAttachment)
let imageMutableAttributedString = NSMutableAttributedString.init(attributedString: imageAttributedString)
let imageParagraphStyle = NSMutableParagraphStyle.init()
imageParagraphStyle.alignment = .center
// one image's length is 1
imageMutableAttributedString.addAttributes([NSParagraphStyleAttributeName : imageParagraphStyle], range: NSRange.init(location: 0, length: imageAttributedString.length))

let summary = "Here is Lenna."
let summaryParagraphStyle = NSMutableParagraphStyle.init()
summaryParagraphStyle.alignment = .center
let summaryAttributes: [String : Any] = [NSFontAttributeName : UIFont.systemFont(ofSize: 18), NSParagraphStyleAttributeName: summaryParagraphStyle]
let summaryAttributedString = NSMutableAttributedString.init(string: summary, attributes : summaryAttributes)
textView.attributedText = textMutableAttributedString

Here is the showcase: UITextView display image and text showcase

NSAttributedString also support for reading and writing text formatting commands and document attributes for a number of popular markup languages, including the following:

  • HTML
  • RTF and RTFD
  • Microsoft Word
  • Word XML
  • WebKit WebArchive
  • ECMA Office Open XML
  • OASIS Open Document

Please see Apple Developer Documents, Attributed String Programming Guide and UITextView.