ios IOS如何在UITextView中添加图片和文字?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24010035/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 00:17:14  来源:igfitidea点击:

How to add image and text in UITextView in IOS?

iosuitextview

提问by rahul

I want to add both text and image in UITextView. The textview should be expanded according to the length of the text and image. In short what I want to do is that when I capture an image from camera or pick from gallery then it should display in UITextView and I should also be able to add some text with that image similar to Facebook.I am also attaching an image that how the UITextView will look like.

我想在 UITextView 中添加文本和图像。textview 应该根据文本和图像的长度进行扩展。简而言之,我想要做的是,当我从相机捕获图像或从图库中选择时,它应该显示在 UITextView 中,并且我还应该能够添加一些带有该图像的文本,类似于 Facebook。我还附加了一个图像UITextView 的外观。

enter image description here

在此处输入图片说明

回答by d2burke

This is absolutely possible now, using

现在这是绝对可能的,使用

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

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

See Apple docs here

在此处查看 Apple 文档

And this example taken from this other answer:

这个例子取自另一个答案

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;

Using the above code will get you an image with text inside a UITextView on iOS 7+. You can/show style the attributed text as you want it and probably set the width of the image to make sure it fits within your textView (as well as setting your own aspect ratio/scale preference)

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

Here's a quick test image:

这是一个快速测试图像:

enter image description here

在此处输入图片说明

回答by Kohei Arai

Thank you for your code, it actually worked. I make a code in the Swift, so I would like to share Swift version of your code. I checked this code works too.

谢谢你的代码,它确实有效。我在 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)

Code For Swift 3.0

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;

回答by jose920405

if you just want place the image in the end, you can use

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

//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)

Check This answer

检查这个答案

回答by Heo ??t Hades

if you want to get the image from the camera, you can try my code below: (Swift 3.0)

如果你想从相机获取图像,你可以试试我下面的代码:(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)
}

回答by George_E

Lots of people are making this a lot more complicated than it needs to be. Firstly, add your image to the catalogue at the right size:

很多人让这件事变得比需要的复杂得多。首先,将您的图像以合适的尺寸添加到目录中:

Twitter logo image

Twitter 徽标图像

Then, create the NSAttributedStringin code:

然后,NSAttributedString在代码中创建:

// Creates the logo image
let twitterLogoImage    = NSTextAttachment()
twitterLogoImage.image  = UIImage(named: "TwitterLogo")
let twitterLogo         = NSAttributedString(attachment: twitterLogoImage)

Then add the NSAttributedStringto what you want:

然后添加NSAttributedString到你想要的:

// Create the mutable attributed string
let text = NSMutableAttributedString(string: "")

/* Code above, creating the logo */
/*    More attributed strings    */

// Add the logo to the whole text
text.append(twitterLogo)
textView.attributedText = text

Or:

或者:

textView.attributedText = twitterLogo

回答by ducnm.isbk

You can refer to how MLLabel work. Main ideal is NSTextAttachment

您可以参考 MLLabel 的工作原理。主要理想是NSTextAttachment

  • Create ImageAttachment extends NSTextAttachment-> override - (nullable UIImage *)imageForBounds:(CGRect)imageBounds textContainer:(nullable NSTextContainer *)textContainer characterIndex:(NSUInteger)charIndexto return image size like you want.
  • Create NSAttributedString with [NSAttributedString attributedStringWithAttachment:ImageAttachment]
  • Create NSMutableAttributedString and append attributed string of ImageAttachment using - (void)replaceCharactersInRange:(NSRange)range withAttributedString:(NSAttributedString *)attrString;
  • Result: You have NSMutableAttributedString contain your image and set it to textView.attributedText
  • 创建 ImageAttachment extends NSTextAttachment-> override - (nullable UIImage *)imageForBounds:(CGRect)imageBounds textContainer:(nullable NSTextContainer *)textContainer characterIndex:(NSUInteger)charIndex以返回您想要的图像大小。
  • 使用[NSAttributedString attributesStringWithAttachment: ImageAttachment]创建 NSAttributedString
  • 创建 NSMutableAttributedString 并使用- (void)replaceCharactersInRange:(NSRange)range withAttributedString:(NSAttributedString *)attrString;附加 ImageAttachment 的属性字符串
  • 结果:您有 NSMutableAttributedString 包含您的图像并将其设置为 textView.attributedText

Sample: HERE

样品:这里

回答by Matloob Hasnain

         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;
                                   }
                               }];

回答by LLIAJLbHOu

Please, try use placeholderTextViewto simple input with icon placeholder support.

请尝试使用placeholderTextView来简单输入并支持图标占位符。

@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()