如何在iOS中的UITextView添加图像和文字?

我想在UITextView中添加文本和图像。 文本视图应根据文本和图像的长度进行扩展。 总之我想做的是,当我从相机捕捉图像或从图库中select,然后它应该显示在UITextView中,我也应该能够添加一些文字与该图像类似于Facebook。我也附上一个图像UITextView的外观如何。

在这里输入图像描述

这是现在绝对可以使用的

+ (NSAttributedString *)attributedStringWithAttachment:(NSTextAttachment *)attachment

请参阅Apple文档

而这个例子取自这个其他的答案 :

 UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0,0,140,140)]; NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"before after"]; NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init]; textAttachment.image = [UIImage imageNamed:@"sample_image.jpg"]; CGFloat oldWidth = textAttachment.image.size.width; //I'm subtracting 10px to make the image display nicely, accounting //for the padding inside the textView CGFloat scaleFactor = oldWidth / (textView.frame.size.width - 10); textAttachment.image = [UIImage imageWithCGImage:textAttachment.image.CGImage scale:scaleFactor orientation:UIImageOrientationUp]; NSAttributedString *attrStringWithImage = [NSAttributedString attributedStringWithAttachment:textAttachment]; [attributedString replaceCharactersInRange:NSMakeRange(6, 1) withAttributedString:attrStringWithImage]; textView.attributedText = attributedString; 

使用上面的代码将在iOS 7 +上的UITextView中获得带有文本的图像。 您可以根据需要/显示样式属性文本,并可能设置图像的宽度以确保它适合您的textView(以及设置您自己的宽高比/缩放比例首选项)

这是一个快速的testing图像:

在这里输入图像描述

感谢您的代码,它实际上工作。 我在Swift中做了一个代码,所以我想分享Swift版本的代码。 我检查了这个代码的作品。

 let textView = UITextView(frame: CGRectMake(50, 50, 200, 300)) let attributedString = NSMutableAttributedString(string: "before after") let textAttachment = NSTextAttachment() textAttachment.image = UIImage(named: "sample_image.jpg")! let oldWidth = textAttachment.image!.size.width; //I'm subtracting 10px to make the image display nicely, accounting //for the padding inside the textView let scaleFactor = oldWidth / (textView.frame.size.width - 10); textAttachment.image = UIImage(CGImage: textAttachment.image!.CGImage, scale: scaleFactor, orientation: .Up) var attrStringWithImage = NSAttributedString(attachment: textAttachment) attributedString.replaceCharactersInRange(NSMakeRange(6, 1), withAttributedString: attrStringWithImage) textView.attributedText = attributedString; self.view.addSubview(textView) 

代码为Swift 3.0

 var attributedString :NSMutableAttributedString! attributedString = NSMutableAttributedString(attributedString:txtBody.attributedText) let textAttachment = NSTextAttachment() textAttachment.image = image let oldWidth = textAttachment.image!.size.width; //I'm subtracting 10px to make the image display nicely, accounting //for the padding inside the textView let scaleFactor = oldWidth / (txtBody.frame.size.width - 10); textAttachment.image = UIImage(cgImage: textAttachment.image!.cgImage!, scale: scaleFactor, orientation: .up) let attrStringWithImage = NSAttributedString(attachment: textAttachment) attributedString.append(attrStringWithImage) txtBody.attributedText = attributedString; 

如果你只是想把图像放在最后,你可以使用

 //create your UIImage let image = UIImage(named: change_arr[indexPath.row]); //create and NSTextAttachment and add your image to it. let attachment = NSTextAttachment() attachment.image = image //put your NSTextAttachment into and attributedString let attString = NSAttributedString(attachment: attachment) //add this attributed string to the current position. textView.textStorage.insertAttributedString(attString, atIndex: textView.selectedRange.location) 

检查这个答案

如果你想从相机获取图像,你可以试试我的代码如下:(Swift 3.0)

 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { let image = info[UIImagePickerControllerOriginalImage] as! UIImage //create and NSTextAttachment and add your image to it. let attachment = NSTextAttachment() attachment.image = image //calculate new size. (-20 because I want to have a litle space on the right of picture) let newImageWidth = (textView.bounds.size.width - 20 ) let scale = newImageWidth/image.size.width let newImageHeight = image.size.height * scale //resize this attachment.bounds = CGRect.init(x: 0, y: 0, width: newImageWidth, height: newImageHeight) //put your NSTextAttachment into and attributedString let attString = NSAttributedString(attachment: attachment) //add this attributed string to the current position. textView.textStorage.insert(attString, at: textView.selectedRange.location) picker.dismiss(animated: true, completion: nil) } 

请尝试使用placeholderTextView来简单地input图标占位符的支持。

 @IBOutlet weak var tvMessage: PlaceholderTextView! let icon: NSTextAttachment = NSTextAttachment() icon.image = UIImage(named: "paper-plane") let iconString = NSMutableAttributedString(attributedString: NSAttributedString(attachment: icon)) tvMessage.icon = icon let textColor = UIColor.gray let lightFont = UIFont(name: "Helvetica-Light", size: tvMessage.font!.pointSize) let italicFont = UIFont(name: "Helvetica-LightOblique", size: tvMessage.font!.pointSize) let message = NSAttributedString(string: " " + "Personal Message", attributes: [ NSFontAttributeName: lightFont!, NSForegroundColorAttributeName: textColor]) iconString.append(message) let option = NSAttributedString(string: " " + "Optional", attributes: [ NSFontAttributeName: italicFont!, NSForegroundColorAttributeName: textColor]) iconString.append(option) tvMessage.attributedPlaceHolder = iconString tvMessage.layoutSubviews() 

你可以参考MLLabel是如何工作的。 主要的理想是NSTextAttachment

  • 创buildImageAttachment扩展NSTextAttachment – > override – (可为空的UIImage *)imageForBounds:(CGRect)imageBounds textContainer:(可为空的NSTextContainer *)textContainer characterIndex:(NSUInteger)charIndex返回图像的大小,像你想要的。
  • 使用[NSAttributedString attributedStringWithAttachment: ImageAttachment ]创buildNSAttributedString
  • 创buildNSMutableAttributedString并追加ImageAttachment的属性string– (void)replaceCharactersInRange:(NSRange)range withAttributedString:(NSAttributedString *)attrString;
  • 结果:你有NSMutableAttributedString包含你的图像,并将其设置为textView.attributedText

样品: 这里

  NSURL *aURL = [NSURL URLWithString:[[NSString stringWithFormat:@"%@%@",Image_BASE_URL,str] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; //UIImage *aImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:aURL]]; //[aImage drawInRect:CGRectMake(0, 0, 20, 20)]; __block NSTextAttachment *imageAttachment = [NSTextAttachment new]; imageAttachment.bounds = CGRectMake(0, -5, 20, 20); NSAttributedString *stringWithImage = [NSAttributedString attributedStringWithAttachment:imageAttachment]; [deCodedString replaceCharactersInRange:NSMakeRange(deCodedString.length, 0) withAttributedString:stringWithImage]; incomingMessage.messageAttributedString = deCodedString; SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader]; imageAttachment.image = [UIImage imageNamed:@"profile_main_placeholder"]; [downloader downloadImageWithURL:aURL options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) { // progression tracking code } completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) { if (image && finished) { [image drawInRect:CGRectMake(0, 0, 20, 20)]; imageAttachment.image = image; dispatch_async(dispatch_get_main_queue(), ^(void) { [self.tbl_Conversation reloadRowsAtIndexPaths:[self.tbl_Conversation indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone]; [self.tbl_Conversation reloadData]; }); // NSAttributedString *stringWithImage = [NSAttributedString attributedStringWithAttachment:imageAttachment]; // [deCodedString replaceCharactersInRange:NSMakeRange(deCodedString.length, 0) withAttributedString:stringWithImage]; // incomingMessage.messageAttributedString = deCodedString; } }];