Ivan Cantarino
Ivan Cantarino

Reputation: 3246

iOS - image attachment for the text view changes attributes

I've a UITextView described as follows with the given attributes:

lazy var inputTextView: UITextView = {
    let tv = UITextView()
    tv.backgroundColor = .white
    tv.textContainerInset = UIEdgeInsetsMake(12, 12, 12, 12) // Posicionamento do texto

    let spacing = NSMutableParagraphStyle()
    spacing.lineSpacing = 4
    let attr = [NSParagraphStyleAttributeName : spacing, NSFontAttributeName: UIFont.systemFont(ofSize: 16),        NSForegroundColorAttributeName: UIColor.blue]
    tv.typingAttributes = attr
    return tv
}()

Everything works as expected until I attach an image to the UITextView.

The image gets inserted in the desired position but after its inserted it overrides my textView attributes.

The text becomes small and in a different color than the attributes I've implemented in its declaration.

I'm attaching the image as follows:

    let att = NSTextAttachment()
    att.image = image
    let attrString = NSAttributedString(attachment: att)
    self.inputTextView.textStorage.insert(attrString, at: self.currentCursorLocation)

What's causing this issue?

I've even tried to reenforce its attributes whenever I insert an UIImage to its content.

I've tried the following when adding the image:

    let att = NSTextAttachment()
    att.image = image
    let attrString = NSAttributedString(attachment: att)
    self.inputTextView.textStorage.insert(attrString, at: self.currentCursorLocation)

    let spacing = NSMutableParagraphStyle()
    spacing.lineSpacing = 4
    let attr = [NSParagraphStyleAttributeName : spacing, NSFontAttributeName: UIFont.systemFont(ofSize: 16), NSForegroundColorAttributeName: UIColor.blue]
    self.inputTextView.typingAttributes = attr

And it still doesn't change its attributes.

Whats causing this issue? Any tip?

Thanks

Edit

As suggested here's how I'm setting the cursor position

func textViewDidChange(_ textView: UITextView) {
    currentCursorLocation = textView.selectedRange.location
}

I do this to insert the image at the current location of the text blinking cursor

Upvotes: 0

Views: 676

Answers (1)

TheBasicMind
TheBasicMind

Reputation: 3585

[Edit: Unfortunately this does not solve Ivan's problem - I leave the answer because it is interesting detail for those who do not understand Unicode character encoding].

String range specification is non-intuitive due to the subtleties of Unicode. I expect your issue is that the cursor position at which you are inserting your image is not where you think it is relative to the text and you are inserting the image at a Unicode scalar position that is not between Unicode code points, such that you are corrupting a unicode code. To understand why this can happen, see this Apple article.

Strings in Swift 2

I would suggest using the following notation when specifying string ranges (taken from this Stack Overflow answer: NSAttributedString and emojis: issue with positions and lengths).

// Convert to NSRange by computing the integer distances:
let nsRange = NSRange(location: text.utf16.distance(from: text.utf16.startIndex, to: from16),
                      length: text.utf16.distance(from: from16, to: to16))

However without seeing how you set your cursor position, it is not possible for me to be sure this is the source of your problem. [Update: thanks for updating the question to show the cursor position - we got there in the end but for others, note, after setting the cursor position this way (which would have been fine), he was incrementing it by 1, which meant the issue I have referred to about Unicode scalars versus code points was in fact the issue].

Upvotes: 1

Related Questions