Here's example code block
let attrString = NSAttributedString(string: "very long string goes here...") // very long string
var currentTextPos = 400 // current text position. ex. 400
let framesetter = CTFramesetterCreateWithAttributedString(attrString as CFAttributedString)
let path = CGPath(rect: UIScreen.main.bounds, transform: nil)
let ctFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(currentTextPos, 0), path, nil)
// draw frame with CTFrameDraw() function later
As an example, imagine we have very long attributed string and we want to draw a frame starting from 400 index.
To draw the next frame, we can just calculate how many characters fits in current frame and draw it. Here's a sample of how to achieve it:
// Get the length of string which fits in current CTFrame object
let frameLength = CTFrameGetVisibleStringRange(ctFrame).length // ex. frameLength == 95
// Append this to our currentTextPos variable
currentTextPos += frameLength // 400 + 95 = 495 . This is our next frame starting position
// Create another frame starting from 495 position
let nextFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(currentTextPos, 0), path, nil)
In this case we are able to get the next CTFrame
object. This is easy to achieve because CTFramesetterCreateFrame
will fill the whole frame with a lines until it reaches the end of frame or until the end of the string. So it's very easy to get the next CTFrame
starting position.
The main question is how to get previous CTFrame
object? Or previous CTFrame
start position?
Imagine that we have only current text position and nothing else. It's also easy to calculate each frame starting positions individually from the beginning of the string till the end and cache it somewhere, but this question became really tricky if we are able to change attributed string font size or smth similar which will change the whole CTFrame
's. After changing font size the CTFrame
object should be drawn from the same currentTextPosition that it was before fontsize changing, in another words, changing font size should not affect current frame start position.