J'essaie d'obtenir l'effet suivant à l'aide d'une UITextView:
En gros, je veux insérer une image entre du texte. L'image peut simplement occuper une rangée d'espace, sans qu'il soit nécessaire de la relier.
J'ai juste essayé d'ajouter UIView à la sous-vue:
UIView *pictureView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 25, 25)];
[pictureView setBackgroundColor:[UIColor redColor]];
[self.textView addSubview:pictureView];
Mais il semble flotter sur le texte et le recouvrir.
J'ai lu un peu sur chemins d'exclusion, ce qui semble être un moyen de mettre cela en œuvre. Cependant, je ne veux pas positionner absolument l'image - elle devrait plutôt suivre le texte (de la même façon que <span>
se comporte en HTML).
Vous devrez utiliser une chaîne attribuée et ajouter l'image en tant qu'instance de 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];
Le code de @ bilobatum converti en Swift pour ceux qui en ont besoin:
let attributedString = NSMutableAttributedString(string: "like after")
let textAttachment = NSTextAttachment()
textAttachment.image = UIImage(named: "whatever.png")
let attrStringWithImage = NSAttributedString(attachment: textAttachment)
attributedString.replaceCharacters(in: NSMakeRange(4, 1), with: attrStringWithImage)
Vous pouvez essayer d'utiliser NSAttributedString et NSTextAttachment. Consultez le lien suivant pour plus de détails sur la personnalisation de NSTextAttachment afin de redimensionner l'image. http://ossh.com.au/design-and-technology/software-development/implementing-rich-text-with-images-on-os-x-and-ios/
Dans mon exemple, je redimensionne l'image pour l'adapter à la largeur. Dans votre cas, vous souhaiterez peut-être redimensionner l'image pour qu'elle corresponde à la hauteur de la ligne.
La solution du problème dans un exemple simple est
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
Développer sur réponse de @ bilobatum et utiliser cette catégorie d'une autre question. J'ai préparé ceci:
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