15

How do I make spacing around NSTextAttachments like in the example below?

In the example No spacing is the default behaviour I get when I append a NSTextAttachment to a NSAttributedString.

enter image description here

Morten Gustafsson
  • 1,869
  • 2
  • 24
  • 34
  • Add white spaces, or add NSKernAttributeName ? There is no default space, it's like writing two letters one after the other, but instead of letter it's images. – Larme Jan 06 '17 at 09:33
  • I tried NSKernAttributeName but it didn't work. – Morten Gustafsson Jan 06 '17 at 09:41
  • 2
    Add `NSAttributedString *space = [[NSAttributedString alloc] initWithString: @" "]` between each of them? – Larme Jan 06 '17 at 15:05
  • A space, like suggested above, doesn't give any precision, but it does work as a quick and ugly fix. – Jonny Mar 01 '18 at 10:59

5 Answers5

7

The above answers no longer worked for me under iOS 15. So I ended up creating and adding an empty "padding" attachment in between the image attachment and attributed text

let padding = NSTextAttachment()
//Use a height of 0 and width of the padding you want
padding.bounds = CGRect(width: 5, height: 0) 
            
let attachment = NSTextAttachment(image: image)
let attachString = NSAttributedString(attachment: attachment)

//Insert the padding at the front
myAttributedString.insert(NSAttributedString(attachment: padding), at: 0)

//Insert the image before the padding
myAttributedString.insert(attachString, at: 0)
simeon
  • 4,466
  • 2
  • 38
  • 42
6

This worked for me in Swift

public extension NSMutableAttributedString {    
    func appendSpacing( points : Float ){
        // zeroWidthSpace is 200B
        let spacing = NSAttributedString(string: "\u{200B}", attributes:[ NSAttributedString.Key.kern: points])
        append(spacing)
    }
}
Jason
  • 1,323
  • 14
  • 19
  • 1
    Hum, it seems to be broken with iOS 15. Maybe a TextKit2 issue. https://stackoverflow.com/q/69312990/3771801 – Ded77 Oct 05 '21 at 13:06
1
NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] init];
// append NSTextAttachments instance to attributedText...
// then add non-printable string with NSKernAttributeName attributes
unichar c[] = { NSAttachmentCharacter };
NSString *nonprintableString = [NSString stringWithCharacters:c length:1];
NSAttributedString *spacing = [[NSAttributedString alloc] initWithString:nonprintableString attributes:@{
    NSKernAttributeName : @(4) // spacing in points
}];
[attributedText appendAttributedString:spacing];

// finally add other text...
ZkTsin
  • 21
  • 3
0

Add spacing to image(For iOS 15).

extension UIImage {
    func imageWithSpacing(insets: UIEdgeInsets) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(
            CGSize(width: self.size.width + insets.left + insets.right,
                   height: self.size.height + insets.top + insets.bottom), false, self.scale)
        UIGraphicsGetCurrentContext()
        let origin = CGPoint(x: insets.left, y: insets.top)
        self.draw(at: origin)
        let imageWithInsets = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return imageWithInsets
    }
}
hstdt
  • 5,652
  • 2
  • 34
  • 34
0

This extension makes it easy to add the space you need. It also works on iOS 16.

extension NSMutableAttributedString {
     func appendSpace(_ width: Double) {
         let space = NSTextAttachment()
         space.bounds = CGRect(x:0, y: 0, width: width, height: 0)
         append(NSAttributedString(attachment: space))
    }
}

// usages
let example = NSMutableAttributedString()
example.appendSpace(42)
...
coco
  • 4,912
  • 2
  • 25
  • 33