Swift 5+
If you want to keep the ratio of the image and the image always centered with the text, then, this is my solution:
extension UILabel {
var mutableAttributedString: NSMutableAttributedString? {
let attributedString: NSMutableAttributedString
if let labelattributedText = self.attributedText {
attributedString = NSMutableAttributedString(attributedString: labelattributedText)
} else {
guard let labelText = self.text else { return nil }
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = self.textAlignment
attributedString = NSMutableAttributedString(string: labelText)
attributedString.addAttribute(NSAttributedString.Key.paragraphStyle,
value: paragraphStyle,
range: NSRange(location: 0, length: attributedString.length))
}
return attributedString
}
func addImage(_ image: UIImage, toEndWith height: CGFloat) {
let fullAttributedString = mutableAttributedString
let imageAttachment = NSTextAttachment()
imageAttachment.image = image
let yImage = (font.capHeight - height).rounded() / 2
let ratio = image.size.width / image.size.height
imageAttachment.bounds = CGRect(x: 0, y: yImage, width: ratio * height, height: height)
let imageString = NSAttributedString(attachment: imageAttachment)
fullAttributedString?.append(imageString)
attributedText = fullAttributedString
}
func addImage(_ image: UIImage, toStartWith height: CGFloat) {
let imageAttachment = NSTextAttachment()
imageAttachment.image = image
let yImage = (font.capHeight - height).rounded() / 2
let ratio = image.size.width / image.size.height
imageAttachment.bounds = CGRect(x: 0, y: yImage, width: ratio * height, height: height)
let fullAttributed = NSMutableAttributedString(attachment: imageAttachment)
if let rawAttributed = mutableAttributedString {
fullAttributed.append(rawAttributed)
}
attributedText = fullAttributed
}
}
And this is how to use the above extension:
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 20))
label.font = .systemFont(ofSize: 20)
let image = UIImage(systemName: "square.and.pencil")!
label.text = "Hi, "
label.addImage(image, toEndWith: 10)
These are some examples:
Using with an attributed string:
let myString = "Hi, "
let myAttribute: [NSAttributedString.Key: UIColor] = [.foregroundColor: .blue]
let myAttrString = NSAttributedString(string: myString, attributes: myAttribute)
label.attributedText = myAttrString
label.addImage(image, toEndWith: 15)