Instruction

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Displaying Writing Tools via UITextInteraction

Adding Writing Tools to your custom views requires two components. The first necessary component is the UITextInteraction. This class is not Writing Tools specific. It was released in iOS 13 and allows the end user to perform selection gestures on your custom text views.

Preparing up a class for Writing Tools

The first thing you need to do is to adopt the UITextInput protocol. Here is a custom text view. Notice that it is a UIView and it also implements the UITextInput protocol.

class CustomSkillsView: UIView, UITextInput{
private var textStorage = NSTextStorage()
private var layoutManager = NSLayoutManager()
private var textContainer = NSTextContainer()
var selectedTextRange: UITextRange?
var markedTextRange: UITextRange?
var markedTextStyle: [NSAttributedString.Key: Any]?
var inputDelegate: UITextInputDelegate?
var tokenizer: UITextInputTokenizer = UITextInputStringTokenizer()

Initializers and Configuration

The initializers for this class are fairly straight forward. They all use a setupInteraction() function to initialize the properties. Most importantly, these initializers setups a connection between the layout manager, the text storage. and the text container. This acts very much like a model-view-controller pattern.

private func setupInteraction() {
  let textInteraction = UITextInteraction(for: .editable)
  textInteraction.textInput = self
  addInteraction(textInteraction)
  textStorage.addLayoutManager(layoutManager)
  layoutManager.addTextContainer(textContainer)
  textContainer.lineFragmentPadding = 0
  // Enable user interaction and set appearance
  isUserInteractionEnabled = true
  backgroundColor = .white
  layer.borderColor = UIColor.gray.cgColor
  layer.borderWidth = 1

  // Initialize selectedTextRange
  selectedTextRange = UITextRangeImpl(range: NSRange(location: 0, length: 0))
}
override var canBecomeFirstResponder: Bool {
  return true
}

Enabling Writing Tools

There is a whole lot more to actually implement in your custom text view. You need to render the text on the screen, enable touch handling, as well as provide SwiftUI support. That’s a lot of code, but what about Writing Tools itself?

func replace(_ range: UITextRange, withText text: String) {
  guard let range = range as? UITextRangeImpl else { return }
  textStorage.replaceCharacters(in: range.nsRange, with: text)
  setNeedsDisplay()
}
See forum comments
Download course materials from Github
Previous: Introduction Next: Conclusion