There is no need for all that code constructing the Text Kit stack, as you are not modifying the architecture of the stack. Just start with a normal UITextView - let's say it's self.textView
- and then assign one or more UIBezierPath objects to its exclusion paths:
self.tv.textContainer.exclusionPaths = myArrayOfBezierPaths;
These paths are exclusion paths, so for an ellipse you will want to make four paths, each one describing a corner of the text container.
Alternatively, you can build the Text Kit stack yourself so as to insert your own text container subclass, and modify where the text is allowed to go by overriding lineFragmentForProposedRect:
, perhaps similar to what I do here: https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch10p537exclusionPath2/ch23p813textKitShapes/MyTextContainer.swift
Some experiments: