A while back I got around the problem with an inelegant workaround, I wrote a function that inserts an empty text attachment into the content to create an horizontal space between the text and the icon:
func addIconToText(_ toText: NSAttributedString, icon: UIImage, iconOrigin: CGPoint, iconSize: CGSize, atEnd: Bool)->NSAttributedString{
// Inserts a textAttachment containing the given icon into the attributed string (at the beginning or at the end of the text depending on the value of atEnd)
// Constructs an empty text attachment to separate the icon from the text instead of using NSTextAttachment.bounds.origin.x because it does not work with iOS 15
let iconTextAttachment = NSTextAttachment(data: icon.withRenderingMode(.alwaysOriginal).pngData(), ofType: "public.png")
iconTextAttachment.bounds = CGRect(origin: CGPoint(x: 0, y: iconOrigin.y), size: iconSize)
let iconString = NSMutableAttributedString(attachment: iconTextAttachment)
let emptyIconSize = CGSize(width: abs(iconOrigin.x), height: abs(iconOrigin.y))
let emptyIconTextAttachment = NSTextAttachment(image: UIGraphicsImageRenderer(size: emptyIconSize).image(actions: {
con in
UIColor.clear.setFill()
con.fill(CGRect(origin: .zero, size: emptyIconSize))
}))
emptyIconTextAttachment.bounds = CGRect(origin: .zero, size: emptyIconSize)
let emptyIconString = NSMutableAttributedString(attachment: emptyIconTextAttachment)
var finalString: NSMutableAttributedString!
if atEnd{
finalString = NSMutableAttributedString(attributedString: toText)
finalString.append(emptyIconString)
finalString.append(iconString)
}else{
finalString = NSMutableAttributedString(attributedString: iconString)
finalString.append(emptyIconString)
finalString.append(toText)
}
return finalString
}