I was trying to follow a tutorial on CoreText and how to draw the text, and I implemented this function in my customView.
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }
let path = CGMutablePath()
path.addRect(bounds)
let attrString = NSAttributedString(string: "Hello World")
let framesetter = CTFramesetterCreateWithAttributedString(attrString as CFAttributedString)
let frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attrString.length), path, nil)
CTFrameDraw(frame, context)
}
It works fine when the text is short but when the text becomes more than 10k letters, it renders in a wrong way. Is there any solution for that?
NOTE: this happen when the text in Arabic not English.
Here is the render when the text is small:
Here is the text render when the text count is too big above 10kb, it appears disjointed and reversed:
Based on your feedback from Apple, it seems that CTFramesetter turns off advanced layout when the string is longer than a certain size. (Their suggestion that this is because there is mixed-direction text doesn't sound right; I've definitely reproduced this with only Arabic.)
To fix this, you need to create a framesetter with a custom typesetter that always does advanced layout (kCTTypesetterOptionAllowUnboundedLayout). Luckily that's straightforward.
Create a custom typesetter first, and then use that to create the framesetter:
let typesetterOptions = [kCTTypesetterOptionAllowUnboundedLayout: true] as CFDictionary
let typesetter = CTTypesetterCreateWithAttributedStringAndOptions(attrString,
typesetterOptions)!
let framesetter = CTFramesetterCreateWithTypesetter(typesetter)