UITextView rich text editing

I need to implement a text editor using UITextView that supports:

  • Bold/Italic/Underline
  • Color,Font,font size changes
  • Paragraph alignment
  • List format (bullets, numbers, etc.)
  • Custom selection of text anywhere in the text view and change the properties

So far I have managed to do it without NSTextStorage but it seems I am hitting limits. For instance, to change font, I use UIFontPickerViewController and change the font as follows:

func fontPickerViewControllerDidPickFont(_ viewController: UIFontPickerViewController) {
         if let selectedFontDesc = viewController.selectedFontDescriptor {
            let font = UIFont(descriptor: selectedFontDesc, size: selectedFontDesc.pointSize)
            self.selectedFont = font
        
            self.textView.typingAttributes = [NSAttributedString.Key.foregroundColor: self.selectedColor ?? UIColor.white, NSAttributedString.Key.font: self.selectedFont ?? UIFont.preferredFont(forTextStyle: .body, compatibleWith: nil)]
        
           if let range = self.textView.selectedTextRange, let selectedFont = selectedFont {
             let attributedText = NSMutableAttributedString(attributedString: self.textView.attributedText)
            
             let location =  textView.offset(from: textView.beginningOfDocument, to: range.start)
             let length = textView.offset(from: range.start, to: range.end)
             let nsRange = NSRange(location: location, length: length)
            
             attributedText.setAttributes([NSAttributedString.Key.font : selectedFont], range: nsRange)
            
             self.textView.attributedText = attributedText
         }
        
     }
 }

This works but the problem is it resets the color of the selected text and other properties. I need to understand a way in which the existing attributed of the text under selection are not disturbed. I suspect the way to do is with using NSTextStorage but I can't find anything good on internet that explains the right use of NSTextStorage to achieve this.

Replies

When you use setAttributes, you replace existing attributes by new ones. Hence, color for instance is reset.

Did you try using mergeAttributes ?

  • No, I didn't. I was not aware of mergeAttributes API, this is the first time I am working on a text editor that requires so many details. Also, I would need to resolve conflicts if they arise while merging attributes. That might require tracking existing attributes for subranges of text. Not sure if I am on the right path for the same.

Add a Comment