tiempo - ¿Cómo agregar imágenes y texto en UITextView en IOS?
iphonizate (7)
Quiero agregar texto e imagen en UITextView. La vista de texto debe ampliarse según la longitud del texto y la imagen. En resumen, lo que quiero hacer es que cuando capture una imagen desde la cámara o la seleccione desde la galería, debería mostrarse en UITextView y también debería poder agregar algo de texto con esa imagen similar a Facebook. También estoy adjuntando una imagen que cómo se verá el UITextView.
Esto es absolutamente posible ahora, usando
+ (NSAttributedString *)attributedStringWithAttachment:(NSTextAttachment *)attachment
Ver los documentos de Apple here
Y este ejemplo tomado de esta otra 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;
Al usar el código anterior, obtendrá una imagen con texto dentro de una UITextView en iOS 7+. Puede / mostrar el estilo del texto atribuido como lo desee y, probablemente, establecer el ancho de la imagen para asegurarse de que se ajuste a su textView (así como establecer su propia relación de aspecto / preferencia de escala)
Aquí hay una imagen de prueba rápida:
Gracias por tu código, realmente funcionó. Hago un código en Swift, así que me gustaría compartir la versión Swift de tu código. Comprobé que este código también funciona.
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)
Código para 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;
Intente utilizar placeholderTextView como entrada simple con soporte de marcador de posición de icono.
@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()
Puede consultar cómo funciona MLLabel. El ideal principal es NSTextAttachment
- Create ImageAttachment extends NSTextAttachment -> override - (nullable UIImage *) imageForBounds: (CGRect) imageBounds textContainer: (nulo NSTextContainer *) textContainer characterIndex: (NSUInteger) charIndex para devolver el tamaño de la imagen como desee.
- Crear NSAttributedString con [NSAttributedString attributedStringWithAttachment: ImageAttachment ]
- Cree NSMutableAttributedString y anexe la cadena atribuida de ImageAttachment usando - (void) replaceCharactersInRange: rango (NSRange) con Atribuido String: (NSAttributedString *) attrString;
- Resultado: tiene NSMutableAttributedString que contiene su imagen y la establece en textView.attributedText
Muestra: HERE
si quieres obtener la imagen de la cámara, puedes probar mi código a continuación: (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)
}
si solo quieres colocar la imagen al final, puedes usar
//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)
Ver esta respuesta
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;
}
}];