29

I have a NSAttributedString to which I am adding a NSTextAttachment. The image is 50w by 50h but I'd like it to scale down to reflect the line height of the attributed string. I thought this would be done automatically but I guess not. I have looked at the UImage class reference but this image doesn't seem to be set in a UIImageView so no access to a frame property. Here's a screenshot of what I currently have:

enter image description here

In an ideal world, I would also like to implement a way to scale up the image based upon user input (such as increasing the font size). Any ideas on how to achieve this?

thx

edit 1

here's how I'm creating it:

    NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
    textAttachment.image = [UIImage imageNamed:@"note-small.png"];
    NSLog(@"here is the scale: %f", textAttachment.image.scale);
    NSAttributedString *attrStringWithImage = [NSAttributedString attributedStringWithAttachment:textAttachment];
    [headerAS replaceCharactersInRange:NSMakeRange([headerAS length], 0) withString:@" "];
    [headerAS replaceCharactersInRange:NSMakeRange([headerAS length], 0) withAttributedString:attrStringWithImage];
Community
  • 1
  • 1
timpone
  • 17,029
  • 31
  • 103
  • 200
  • It will help you http://stackoverflow.com/questions/26105803/center-nstextattachment-image-next-to-single-line-uilabel – Vinayak Mar 30 '16 at 12:53

5 Answers5

66

You should set bounds form attachment to resize image like this:

attachment.bounds = CGRectMake(0, 0, yourImgWidth, yourImgHeight)

Fangming
  • 20,957
  • 4
  • 91
  • 84
Dung Nguyen
  • 705
  • 1
  • 6
  • 7
28

If you need to resize a bunch of NSTextAttachment images while keeping their aspect ratio i've written a handy extension: http://hack.swic.name/convenient-nstextattachment-image-resizing

extension NSTextAttachment {
    func setImageHeight(height: CGFloat) {
        guard let image = image else { return }
        let ratio = image.size.width / image.size.height

        bounds = CGRect(x: bounds.origin.x, y: bounds.origin.y, width: ratio * height, height: height)
    }
}

Example usage:

let textAttachment = NSTextAttachment()
textAttachment.image = UIImage(named: "Image")
textAttachment.setImageHeight(16) // Whatever you need to match your font

let imageString = NSAttributedString(attachment: textAttachment)
yourAttributedString.appendAttributedString(imageString)
hasan
  • 22,029
  • 10
  • 58
  • 94
Maciej Swic
  • 10,562
  • 8
  • 46
  • 64
16

Look at subclassing NSTextAttachment and implementing the NSTextAttachmentContainer methods to return different sizes based on the text container supplied. By default, NSTextAttachment just returns the size of the image it is provided with.

Wain
  • 117,132
  • 14
  • 131
  • 151
3

Swift4 if you want a attributed string along with the image or a icon

here you can do something like this.

func AttributedTextwithImgaeSuffixAndPrefix(AttributeImage1 : UIImage , AttributedText : String ,AttributeImage2 : UIImage,  LabelBound : UILabel) -> NSMutableAttributedString
{
    let fullString = NSMutableAttributedString(string: "  ")
    let image1Attachment = NSTextAttachment()
    image1Attachment.bounds = CGRect(x: 0, y: ((LabelBound.font.capHeight) - AttributeImage1.size.height).rounded() / 2, width: AttributeImage1.size.width, height: AttributeImage1.size.height)
    image1Attachment.image = AttributeImage1
    let image1String = NSAttributedString(attachment: image1Attachment)
    let image2Attachment = NSTextAttachment()
    image2Attachment.bounds = CGRect(x: 0, y: ((LabelBound.font.capHeight) - AttributeImage2.size.height).rounded() / 2, width: AttributeImage2.size.width, height: AttributeImage2.size.height)
    image2Attachment.image = AttributeImage2
    let image2String = NSAttributedString(attachment: image2Attachment)
    fullString.append(image1String)
    fullString.append(NSAttributedString(string: AttributedText))
    fullString.append(image2String)
    return fullString
}

you can use this code as mentioned below:

        self.lblMid.attributedText = AttributedTextwithImgaeSuffixAndPrefix(AttributeImage1: #imageLiteral(resourceName: "Left") , AttributedText: "  Payment Details  ", AttributeImage2: #imageLiteral(resourceName: "RIght") , LabelBound: self.lblMid)

here you can add images you can replace it with your own:

Left Image enter image description here

Right Image enter image description here

Out put will be like this enter image description here

Azharhussain Shaikh
  • 1,399
  • 10
  • 12
0

NSTextAtatchment is just a holder for a UIImage so scale the image when it needs scaling and recreate the text attachment or set it's image. You'll need to force a nslayout update if you change the image on an existing text attachment.

scottdev
  • 141
  • 2