5

I receive as an input a NSAttributedString that may contain an image attached as NSTextAttachment. I need to check if actually such image is attached and, in such case, remove it. I've been looking for related posts with no success, how could I do this?

EDIT: I'm trying this:

let mutableAttrStr = NSMutableAttributedString(attributedString: textView.attributedText)
textView.attributedText.enumerateAttribute(NSAttachmentAttributeName, in: NSMakeRange(0, textView.attributedText.length), options: NSAttributedString.EnumerationOptions(rawValue: 0)) { (value, range, stop) in

            if (value as? NSTextAttachment) != nil {
                mutableAttrStr.replaceCharacters(in: range, with: NSAttributedString(string: ""))
            }
        }

If the textView.attributedText contains more than one attachment (I see several \u{ef} in its string), I expected the enumeration to match the condition if (value as? NSTextAttachment) != nil several times but that block of code is only executed once.

How can I remove all attachments?

AppsDev
  • 12,319
  • 23
  • 93
  • 186
  • Could you search and remove any attachment characters: https://developer.apple.com/reference/uikit/nstextattachment/1508411-attachment_character – MathewS Jan 08 '17 at 17:49
  • 1
    Enumerate the attributedString for `NSAttachmentAttributeName`, and remove them. Here a code you can look: http://stackoverflow.com/questions/29152660/extract-uiimage-from-nsattributed-string/29153172#29153172 – Larme Jan 08 '17 at 20:31
  • @MathewS thanks, and what the most appropriate way to enumerate the characters of an `NSAttributedString` to check if `NSAttachmentCharacter` should be? – AppsDev Jan 09 '17 at 11:40
  • If you have other attributes set that you want to preserve, I'd base the enumeration from what's shown in the link @Larme posted. Otherwise you could just get the attributed string's `text` property and use `replacingOccurrences(of: with:)` – MathewS Jan 09 '17 at 13:59
  • To remove a part: http://stackoverflow.com/questions/37951812/delete-remove-nstextattachment-from-uitextview/37952099#37952099 as said by MathewsS – Larme Jan 09 '17 at 14:01

1 Answers1

8

Swift 4, XCode 9 answer:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

    picker.dismiss(animated: true, completion: nil)

    guard let image = info["UIImagePickerControllerOriginalImage"] as? UIImage else {
        return
    }

//check if textview contains any attachment     

txtView.attributedText.enumerateAttribute(NSAttributedStringKey.attachment, in: NSRange(location: 0, length: txtView.attributedText.length), options: []) { (value, range, stop) in

        if (value is NSTextAttachment){
           let attachment: NSTextAttachment? = (value as? NSTextAttachment)

            if ((attachment?.image) != nil) {
               print("1 image attached")
                let mutableAttr = txtView.attributedText.mutableCopy() as! NSMutableAttributedString
                //Remove the attachment
                mutableAttr.replaceCharacters(in: range, with: "")
                txtView.attributedText = mutableAttr

            }else{
                print("No image attched")
            }
        }
    }
   //insert only one selected image into TextView at the end
    let attachment = NSTextAttachment()
    attachment.image = image
    let newWidth = txtView.bounds.width - 20
    let scale = newWidth / image.size.width

    let newHeight = image.size.height * scale
    attachment.bounds = CGRect.init(x: 0, y: 0, width: newWidth, height: newHeight)
    let attrString = NSAttributedString(attachment: attachment)
    txtView.textStorage.insert(attrString, at: txtView.selectedRange.location)

}
Nupur Sharma
  • 1,106
  • 13
  • 15