iOS 7 TextKit - Как вставить изображения, встроенные в текст?
Я пытаюсь получить следующий эффект с помощью UITextView:
В основном я хочу вставить изображение между текстом. Изображение может просто занимать 1 строку пространства, поэтому нет необходимости в переносе.
Я попытался просто добавить UIView к подпредставлению:
UIView *pictureView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
[pictureView setBackgroundColor:[UIColor redColor]];
[self.textView addSubview:pictureView];
Но, похоже, он всплывает над текстом и закрывает его.
Я немного читал о путях исключения, которые, кажется, являются одним из способов реализации этого. Тем не менее, я не хочу абсолютно позиционировать изображение - вместо этого оно должно течь с текстом (аналогично тому, как <span>
ведет себя в HTML).
5 ответов
Вам нужно будет использовать приписанную строку и добавить изображение в качестве экземпляра 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];
Код @bilobatum, преобразованный в Swift для нуждающихся:
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)
Вы можете попробовать использовать NSAttributedString и NSTextAttachment. Посмотрите следующую ссылку для получения дополнительной информации о настройке NSTextAttachment для изменения размера изображения. http://ossh.com.au/design-and-technology/software-development/implementing-rich-text-with-images-on-os-x-and-ios/
В моем примере я изменяю размер изображения, чтобы соответствовать ширине, в вашем случае вы можете изменить размер изображения, чтобы соответствовать высоте линии.
Решение проблемы в простом примере
let attachment = NSTextAttachment()
attachment.image = UIImage(named: "qrcode")
let iconStringdString = NSAttributedString(attachment: attachment)
let fString = NSMutableAttributedString(string: "scan the ")
let sString = NSAttributedString(string: "QR code received on your phone.")
fString.append(iconStringdString)
fString.append(sString)
self.textLabel.attributedText = fString
Расширение ответа@bilobatum и использование этой категории из другого вопроса. Я приготовил это:
Использование:
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;
Реализация:
@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