How to add images as text attachment in Swift using nsattributedstring

add image to uilabel swift 4
nstextattachment image size
nstextattachment image tap
add image in textview swift
nstextattachment uiview
nsattributedstring add attribute
nsattributedstring clickable text swift
swift emoji to image

I'm trying to build a custom keyboard for iOS using images which I've put in as buttons. When I press a button, the image linked to the button is put into an attributed string which is loaded into an UiTextView inside the custom keyboard view. That is working.

The problem is that when I append a new image to the attributed string both the old and new images in the string are changing to the image I currently pressed on. I can't understand why the old images in the string are changing.

Any suggestions? I've tried using replaceCharactersInRange and insertAttributedString but can't get it to work. Here is the code (after viewDidLoad):

let textAttachment = NSTextAttachment()

let textView = UITextView(frame: CGRectMake(5, 5, 200, 40))
var attributedString = NSMutableAttributedString(string: "")

@IBAction func buttonPressed(button :UIButton) {

    let string = button.titleLabel?.text

    textAttachment.image = UIImage(named: "\(string!).png")!
    textAttachment.image = UIImage(CGImage: textAttachment.image!.CGImage!, scale: 6, orientation: .Up)
    let attrStringWithImage = NSAttributedString(attachment: textAttachment)
    attributedString.appendAttributedString(attrStringWithImage);


    textView.attributedText = attributedString;
  }

Thank you!

We cannot simply append NSTextAttachment image .We have to store all the attached Image and concatenation to existing attributed String.

func buttonPressed(_ sender: Any) {

    let  button = sender as! UIButton
    let tag =  button.tag
    let attributedString:NSAttributedString!

    switch tag {
    case 2:
        attributedString = addAttributedText(text: (button.titleLabel?.text)!)
    case 3:
        attributedString = addAttributedText(text: (button.titleLabel?.text)!)
    case 4:
        attributedString = addAttributedText(text: (button.titleLabel?.text)!)
    default:
       attributedString = addAttributedText(text: "launch")
      }
        textView.attributedText = attributedString
    }

    func addAttributedText(text:String) -> NSAttributedString {
        textViewDidChange(textView)
        let axtractedImageAttribute = NSMutableAttributedString()
        for image in imageArray {
            let attachment:NSTextAttachment = NSTextAttachment()
            attachment.image = image
            attachment.setImageHeight(height: 20)
            let attachmentString:NSAttributedString = NSAttributedString(attachment: attachment)
            axtractedImageAttribute.append(attachmentString)
        }

        let attachment:NSTextAttachment = NSTextAttachment()
        attachment.image = UIImage(named: "\(text).png")
        attachment.setImageHeight(height: 20)
        let attachmentString:NSAttributedString = NSAttributedString(attachment: attachment)
        let attributedString:NSMutableAttributedString = NSMutableAttributedString(string:textView.text!)
        attributedString.append(axtractedImageAttribute)
        attributedString.append(attachmentString)
        return attributedString
    }

    //MARKS:-  Extract attachedImage
    func textViewDidChange(_ textView: UITextView)  {
        imageArray = [UIImage]()
        let range = NSRange(location: 0, length: textView.attributedText.length)
        if (textView.textStorage.containsAttachments(in: range)) {
            let attrString = textView.attributedText
            var location = 0
            while location < range.length {
                var r = NSRange()
                let attrDictionary = attrString?.attributes(at: location, effectiveRange: &r)
                if attrDictionary != nil {
                    let attachment = attrDictionary![NSAttachmentAttributeName] as? NSTextAttachment
                    if attachment != nil {
                        if attachment!.image != nil {
                            imageArray.append( attachment!.image!)
                        }
                    }
                    location += r.length
                }
            }
        }
    }

}

Demo Reference

How to add images as text attachment in Swift using nsattributedstring. I'm trying to build a custom keyboard for iOS using images which I've put in as buttons. When I press a button, the image linked to the button is put into an attributed string which is loaded into an UiTextView inside the custom keyboard view. Questions: I’m trying to build a custom keyboard for iOS using images which I’ve put in as buttons. When I press a button, the image linked to the button is put into an attributed string which is loaded into an UiTextView inside the custom keyboard view.

I found the problem, I need to have different variables for the NSTextAttachment (ie. textAttachment1, textAttachment2 etc.) otherwise it just uses the first image that was addressed.

I found on Style.swift support to NSTextAttachment, but not on README. I create a Style, set an attach with an image, apply to the text and nothing /how-​to-insert-images-into-an-attributed-string-with-nstextattachment. If you are able to use it, there is a much simpler suggestion: NSAttributedString and NSTextAttachment. Attributed strings are strings with formatting attached (bold, italics, alignment, colors, etc), but you can also attach images inside attributed strings, and they just get drawn right along with the text.

This works for me:

let attributedStringTextAttachment = NSTextAttachment()
attributedStringTextAttachment.image = UIImage(named: "image")

This label will be used to create our interactive text with funny emojis. Next, let's create a Attach image to the attributed string let attachment  Now the basic NSAttributedString implementation. Now let’s get our hands dirty with the coding part. First let’s update the text and change its color only using the textColor property only. Let’s add the following lines in the viewDidLoad function and run the app again.

This is my extension Swift 4, to change image to attributed String with size and tint color change

public extension UIImage {

    func tint(with color: UIColor) -> UIImage {
        var image = withRenderingMode(.alwaysTemplate)
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        color.set()

        image.draw(in: CGRect(origin: .zero, size: size))
        image = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }

    func toAttributedString(with heightRatio: CGFloat, tint color: UIColor? = nil) -> NSAttributedString {
        let attachment = NSTextAttachment()
        var image = self

        if let tintColor = color {
            image.withRenderingMode(.alwaysTemplate)
            image = image.tint(with: tintColor)
        }

        attachment.image = image

        let ratio: CGFloat = image.size.width / image.size.height
        let attachmentBounds = attachment.bounds

        attachment.bounds = CGRect(x: attachmentBounds.origin.x,
                                   y: attachmentBounds.origin.y,
                                   width: ratio * heightRatio,
                                   height: heightRatio)

        return NSAttributedString(attachment: attachment)
    }
}

How to add images as text attachment in Swift using nsattributedstring - ios. The problem is that when I append a new image to the attributed string both the  Third, we can wrap that attachment inside its own attributed string so we can append it to the previous string: let image1String = NSAttributedString(attachment: image1Attachment) Finally, we can add the NSTextAttachment wrapper to our full string: fullString.append(image1String) That’s it – an image inside our attributed string!

I'm trying to build a custom keyboard for iOS using images which I've put in as buttons. When I press a button, the image linked to the button is  Define a paragraph style that aligns text to the center. Create an attributes dictionary containing that paragraph style, and also a font. Wrap that attributes dictionary and a string into an instance of NSAttributedString. Load an image from the project and draw it to the context. Update the image view with the finished result.

iOS 7.0+; macOS 10.0+; Mac Catalyst 13.0+; tvOS 9.0+ The NSAttributedString class cluster uses text attachment objects as the values init(image: UIImage). As NSAttributedString is primarily used with Core Text on iOS, you have to use CTParagraphStyle instead of NSParagraphStyle. There is no mutable variant. For example: CTTextAlignment alignment = kCTCenterTextAlignment; CTParagraphStyleSetting alignmentSetting; alignmentSetting.spec = kCTParagraphStyleSpecifierAlignment; alignmentSetting.valueSize = sizeof(CTTextAlignment); alignmentSetting.value = &alignment; CTParagraphStyleSetting settings[1] = {alignmentSetting}; size_t settingsCount = 1;

First introduced in iOS 7 (though it took a while, macOS had this since about any Auto Layout rules, it just gets drawn right along with the text. 28.0)!]// create NSMutableAttributedString that we'll append string & image tolet  NSTextAttachment has a default image attribute and the attachment is stored as part of the NSAttributedString. You probably could create your own subclasses and store whatever you want. I think display is limited to displaying an image so not sure a UIView would be useful.

Comments
  • You're re-using the same textAttachment for each image, that's your problem. Simply create a new NSTextAttachment() each time, and no need to store it.
  • If I have 2 different images attached, how could I recognize which one im clicking? I did make the code to print something when an image attachment is clicked, but I need to realize different actions depending on the image.
  • Also, is it possible to attach a video?
  • how to provide action to this image attached to string?
  • @Shrawan What about "some text" + image + "again some text "+image