IOS 7 TextKit - How to embed images in a string with text?

I am trying to get the following effect using a UITextView:

enter image description here

Basically I want to insert an image between the text. An image can simply just take up 1 line of space, so there is no need for packaging.

I tried just adding a UIView to the subview:

UIView *pictureView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)]; [pictureView setBackgroundColor:[UIColor redColor]]; [self.textView addSubview:pictureView]; 

But he seems to float over the text and cover it.

I read a little on the path of exception , which seems to be one way to implement it. However, I do not want to absolutely position the image - instead, it should flow with the text (similar to how <span> behaves in HTML).

+98
ios ios7 textkit
Jan 05 '14 at 5:30
source share
5 answers

You will need to use the sent string and add the image as an instance of NSTextAttachment :

 NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"like after"]; NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init]; textAttachment.image = [UIImage imageNamed:@"whatever.png"]; NSAttributedString *attrStringWithImage = [NSAttributedString attributedStringWithAttachment:textAttachment]; [attributedString replaceCharactersInRange:NSMakeRange(4, 1) withAttributedString:attrStringWithImage]; 
+169
Jan 05 '14 at 5:57
source share

You can try using NSAttributedString and NSTextAttachment. Take a look at the following link for more information on setting up NSTextAttachment to resize an image. http://ossh.com.au/design-and-technology/software-development/implementing-rich-text-with-images-on-os-x-and-ios/

In my example, I resize the image to fit the width, in your case you can resize the image to fit the height of the line.

+20
Jan 05 '14 at 5:54 on
source share

@bilobatum converted to Swift for those who need it:

 var attributedString = NSMutableAttributedString(string: "like after") var textAttachment = NSTextAttachment() textAttachment.image = UIImage(named: "whatever.png") var attrStringWithImage = NSAttributedString.attributedStringWithAttachment(textAttachment) attributedString.replaceCharactersInRange(NSMakeRange(4, 1), withAttributedString: attrStringWithImage) 
+20
Jan 19 '16 at 22:52
source share

Extending to @bilobatum answer and using this category from another question. I have prepared this:

Using:

 UILabel *labelWithImage = [UILabel new]; labelWithImage.text = @"Tap [new-button] to make a new thing!"; NSAttributedString *stringWithImage = [labelWithImage.attributedText attributedStringByReplacingOccurancesOfString:@"[new-button]" withImage:[UIImage imageNamed:@"MyNewThingButtonImage"] scale:0]; labelWithImage.attributedText = stringWithImage; 

Implementation:

 @interface NSMutableAttributedString (InlineImage) - (void)replaceCharactersInRange:(NSRange)range withInlineImage:(UIImage *)inlineImage scale:(CGFloat)inlineImageScale; @end @interface NSAttributedString (InlineImages) - (NSAttributedString *)attributedStringByReplacingOccurancesOfString:(NSString *)string withInlineImage:(UIImage *)inlineImage scale:(CGFloat)inlineImageScale; @end 

.

 @implementation NSMutableAttributedString (InlineImages) - (void)replaceCharactersInRange:(NSRange)range withInlineImage:(UIImage *)inlineImage scale:(CGFloat)inlineImageScale { if (floorf(inlineImageScale) == 0) inlineImageScale = 1.0f; // Create resized, tinted image matching font size and (text) color UIImage *imageMatchingFont = [inlineImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; { // Font size NSDictionary *attributesForRange = [self attributesAtIndex:range.location effectiveRange:nil]; UIFont *fontForRange = [attributesForRange valueForKey:NSFontAttributeName]; CGSize imageSizeMatchingFontSize = CGSizeMake(inlineImage.size.width * (fontForRange.capHeight / inlineImage.size.height), fontForRange.capHeight); // Some scaling for prettiness CGFloat defaultScale = 1.4f; imageSizeMatchingFontSize = CGSizeMake(imageSizeMatchingFontSize.width * defaultScale, imageSizeMatchingFontSize.height * defaultScale); imageSizeMatchingFontSize = CGSizeMake(imageSizeMatchingFontSize.width * inlineImageScale, imageSizeMatchingFontSize.height * inlineImageScale); imageSizeMatchingFontSize = CGSizeMake(ceilf(imageSizeMatchingFontSize.width), ceilf(imageSizeMatchingFontSize.height)); // Text color UIColor *textColorForRange = [attributesForRange valueForKey:NSForegroundColorAttributeName]; // Make the matching image UIGraphicsBeginImageContextWithOptions(imageSizeMatchingFontSize, NO, 0.0f); [textColorForRange set]; [inlineImage drawInRect:CGRectMake(0 , 0, imageSizeMatchingFontSize.width, imageSizeMatchingFontSize.height)]; imageMatchingFont = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); } // Text attachment with image NSTextAttachment *textAttachment = [NSTextAttachment new]; textAttachment.image = imageMatchingFont; NSAttributedString *imageString = [NSAttributedString attributedStringWithAttachment:textAttachment]; [self replaceCharactersInRange:range withAttributedString:imageString]; } @end @implementation NSAttributedString (InlineImages) - (NSAttributedString *)attributedStringByReplacingOccurancesOfString:(NSString *)string withInlineImage:(UIImage *)inlineImage scale:(CGFloat)inlineImageScale { NSMutableAttributedString *attributedStringWithImages = [self mutableCopy]; [attributedStringWithImages.string enumerateOccurancesOfString:string usingBlock:^(NSRange substringRange, BOOL *stop) { [attributedStringWithImages replaceCharactersInRange:substringRange withInlineImage:inlineImage scale:inlineImageScale]; }]; return [attributedStringWithImages copy]; } @end 
+4
Aug 25 '16 at 11:47
source share

The solution to the problem in a simple example is enter image description here

 let attachment = NSTextAttachment() attachment.image = UIImage(named: "qrcode") let iconString = NSAttributedString(attachment: attachment) let firstString = NSMutableAttributedString(string: "scan the ") let secondString = NSAttributedString(string: "QR code received on your phone.") firstString.append(iconString) firstString.append(secondString) self.textLabel.attributedText = firstString 
+2
Jun 29 '18 at 18:04
source share



All Articles