I've tried so many different things based on what I found online and still can't do this. There are similar questions that I have tried to piece together but it's still not working. Here is what I have so far:
class CustomUITextView: UITextView {
override func paste(sender: AnyObject?) {
let data: NSData? = UIPasteboard.generalPasteboard().dataForPasteboardType("public.png")
if data != nil {
let attributedString = self.attributedText.mutableCopy() as! NSMutableAttributedString
let textAttachment = NSTextAttachment()
textAttachment.image = UIImage(data: data!)
let attrStringWithImage = NSAttributedString(attachment: textAttachment)
attributedString.replaceCharactersInRange(self.selectedRange, withAttributedString: attrStringWithImage)
self.attributedText = attributedString
} else {
let pasteBoard: UIPasteboard = UIPasteboard.generalPasteboard()
let text = NSAttributedString(string: pasteBoard.string!)
let attributedString = self.attributedText.mutableCopy() as! NSMutableAttributedString
attributedString.replaceCharactersInRange(self.selectedRange, withAttributedString: text)
self.attributedText = attributedString
}
}
}
Also, my IBOutlet for the textView is in another file and is of this custom type I created:
#IBOutlet var textView: CustomUITextView!
I created a subclass of UITextView and assigned it to my textview. I then override the paste function to allow for images since I read that UITextField does not support image pasting by default. This is currently working for the text but not the image ---> if I do a long press gesture to show the Menu, the "Paste" button never shows up if there is an image in the PasteBoard; it only shows if there is text.
Ultimately, I want to paste PNG, JPEGS, and images from URLS in my textview. Someone please help !!
Related
I'm a swift novice and I hope someone can help.
I want to insert text with a new color and font through a button into the text field (that uses another color and font). Not deleting the original text in the field or change its font or color.
I have managed to insert text thought the button, but no using the NSAttributedString. Don't know if the code in the IBAction will even work, usure where to place the:
let attributedTest = NSAttributedString
let test = "Testing here"
let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont(name:"AvenirNext-Italic", size: 40)!,
.foregroundColor: UIColor.red,
]
let attributedTest = NSAttributedString(string: test, attributes: attributes as [NSAttributedString.Key : Any])
#IBAction func justTesting(_ sender: UIButton) {
noteTextView.text = noteTextView.text! + String(attributedTest)
}
You can use this extension to append attributed string
extension NSMutableAttributedString{
func getAttributedStringByAppending(attributedString:NSMutableAttributedString) -> NSMutableAttributedString{
let newAttributedString = NSMutableAttributedString()
newAttributedString.append(self)
newAttributedString.append(attributedString)
return newAttributedString
}
}
#IBAction func justTesting(_ sender: UIButton) {
let noteTextView = UITextView()
noteTextView.text = NSMutableAttributedString(string: noteTextView.text).getAttributedStringByAppending(attributedString: attributedTest)
}
I have a UITextView where I want to allow the user to insert photos from the photo library and PDFs from a document picker.
It is quite easy to embed a photo into the text view attributed string:
let attachment = NSTextAttachment(data: image.jpegData(1.0), ofType: kUTTypeJPEG as String)
attachment.bounds = CGRect(origin: CGPoint.zero, size: CGSize(width: 40, height: 40))
let attachmentString = NSAttributedString(attachment: attachment)
let text = NSMutableAttributedString(attributedString: textView.attributedText)
text.append(attachmentString)
textView.attributedText = text
This works perfectly for a photo: the image displays in the UITextView and the attachment is retrievable from the attributedText:
textView.attributedText.enumerateAttribute(.attachment, in: NSMakeRange(0, attributedText.length), options: []) { (item, range, ptr) in
if let attachment = item as? NSTextAttachment {
files.append(FileAttachment(data: attachment.contents, type: attachment.fileType))
}
The problem comes when trying to attach a PDF.
If I follow the exact same pattern with a PDF, replacing the data with PDF data and file type with kUTTypePDF, the attachment is created but does not display anything in the UITextView.
I should simply be able to set an image on the NSTextAttachment as a representation of the contents but this resets the attachment data.
let data = Data(contentsOf: pdfURL)
let attachment = NSTextAttachment(data: data, ofType: kUTTypePDF as String)
attachment.image = UIImage(named: "pdf-document-icon")
attachment.bounds = CGRect(origin: CGPoint.zero, size: CGSize(width: 40, height: 40))
let attachmentString = NSAttributedString(attachment: attachment)
let text = NSMutableAttributedString(attributedString: textView.attributedText)
text.append(attachmentString)
textView.attributedText = text
Now, the PDF attachment displays in the text view as a nice icon, but later when I enumerate the attachments the contents and file type are nil. i.e. setting an image on NSTextAttachment resets contents and fileType
I need to both set content and separate image representing the content on NSTextAttachment.
The best solution I have come up with so far is to subclass NSTextAttachment:
class TextAttachmentWithThumbnail: NSTextAttachment {
private var thumbnail: UIImage?
override var image: UIImage? {
get { return thumbnail }
set { thumbnail = newValue }
}
}
So that setting an image no longer resets contents and fileType
Is there any way I can just make the text center and change the size/font?
I set it in storyboard but nothing happen when I ran the app. I also tried to use UILabel but it didn't work (when I click it the web didn't show)
The answer I found they didn't include the URL just attributes.paragraphstyle.
I don't know how to write it so I can keep the URL string also change the font/size/alignment.
func searchMealRecipe() {
MealRecipeService.sharedInstance.foodID = foodID
MealRecipeService.sharedInstance.getMealRecipe { (responseString, mealRecipeItem) in
if responseString == "error" {
/* popup here alerting user about error*/
} else {
self.mealRecipeItem = mealRecipeItem
self.ingredientRecipeTitleLabel.text = (mealRecipeItem.name)?.htmlString?.string
self.ingredientRecipeImageView.sd_setImage(with: URL(string: mealRecipeItem.imageURL!), placeholderImage: UIImage(named: ""))
self.ingredientRecipeTextView.text = mealRecipeItem.ingredients?.joined(separator: "\n")
let string = "Sounds Good! Show Me the Steps 📖"
let attributedString = NSMutableAttributedString(string: string, attributes:[NSAttributedString.Key.link: URL(string: "\(mealRecipeItem.link!)")!])
self.ingredientRecipeLinkTextView.attributedText = attributedString
}
}
}
I'm using xcode10 beta and swift4.2
//Update(I figured it out the answer and it's working)
//the attributes accept array so I can put multiple styles in the array.
let string = "Sounds Good! Show Me the Steps 📖"
let style = NSMutableParagraphStyle()
style.alignment = NSTextAlignment.center
let attributedString = NSMutableAttributedString(string: string, attributes:[NSAttributedString.Key.link: URL(string: "\(mealRecipeItem.link!)")!, NSAttributedString.Key.paragraphStyle: style])
self.ingredientRecipeLinkTextView.attributedText = attributedString
you can use NSMutableParagraphStyle
let style = NSMutableParagraphStyle()
style.alignment = NSTextAlignment.center
lbl.centerAttributedText = NSAttributedString(string: "Total Balance",attributes: [your Attributed URL Code here])
I want to replace "[img src=(IMAGE NAME)]" text to (IMAGE NAME) image.
but text replaced with blank. not an image. what should i do?
guard
let original = self.text
else { return }
let pattern = "\\[img src=(\\w+)\\]"
do{
let regex = try NSRegularExpression(pattern: pattern, options: [])
let matches = regex.matches(in: original, options : [], range : NSMakeRange(0, original.characters.count))
let attributeString = NSMutableAttributedString(string : original)
for match in matches.reversed(){
let emoticon = attributeString.attributedSubstring(from: match.rangeAt(1)).string
if let image = UIImage(named : "\(emoticon)"){
let attributedImage = NSTextAttachment()
attributedImage.image = image
attributedImage.bounds = CGRect(x : 0, y : 0, width : image.size.width, height : image.size.height)
attributeString.replaceCharacters(in: match.rangeAt(0), with: NSAttributedString(attachment: attributedImage))
}
}
self.attributedText = attributeString
}catch{
}
ou can't do this. Neither in swift nor objective-c.
The thing to do is to store the data you want to retrieve. That is... store the name somewhere and use that to load the image. Not the other way around.
So create a property something like imageName and then use that as image name.
I solved this problem. NSTextAttachment with Image cannot display in UITextField. but, In UITextView with edit mode, can display the Image.
I am wondering how Venmo places custom emoticons into their textfield.
When you copy these images and paste them elsewhere, they show up as ":sunset:", ":concert:", etc.
So my guess is the textField delegate checks for any text that matches that pattern (i.e. ":concert:") and replaces it with a tiny image.
So I am wondering how you can place your own little UIImageView within a textField alongside other text.
Edit: This could also be a UITextView now that I think about it
The text input in the screenshot is almost definitely a custom subclass of UITextView, and here I'll present one way to achieve the desired result with just that.
Here's a short demonstration, copying text containing a custom image from one UITextView to another:
First we'll need to subclass NSTextAttachment to have a textual representation of the image at hand, which we'll later use when copying.
class TextAttachment: NSTextAttachment {
var representation: String?
}
Now when we create an attributed string containing the image, we'll add the desired textual representation of the image to the attachment:
let attachment = TextAttachment()
attachment.image = UIImage(named: "1f197")
attachment.representation = ":anything-here:"
Next, we'll subclass UITextView and override the copy(_:) method declared in UIResponderStandardEditActions which UITextView implements.
class TextView: UITextView {
override func copy(_ sender: Any?) {
let selectedString = self.attributedText.attributedSubstring(from: self.selectedRange)
let enumeratableRange = NSRange(location: 0, length: selectedString.length)
let result = NSMutableAttributedString(attributedString: selectedString)
selectedString.enumerateAttribute(NSAttachmentAttributeName, in: enumeratableRange, options: []) { (value, range, _) in
if let attachment = value as? TextAttachment, let representation = attachment.representation {
result.replaceCharacters(in: range, with: representation)
}
}
UIPasteboard.general.string = result.string
}
}
We could also override a few other methods, such as cut(_:) and paste(_:), but that's outside the scope of the question.
Finally, let's add some attributed text to an instance of the custom text view to see how it performs in action:
var textView: TextView // Create an instance however.
let mutableString = NSMutableAttributedString()
mutableString.append(NSAttributedString(string: "Text with "))
mutableString.append(NSAttributedString(attachment: attachment))
mutableString.append(NSAttributedString(string: " text attachment."))
self.textView.attributedText = mutableString
Obviously it would be more intuitive to convert text/emoji/whatever into attachments on the fly while the user is typing.