hello everyone,
I am coming to the conclusion of the development of this blessed label that allows you to view Asian text with a phonetic guide. By searching the internet and also reading the @lyndsey tutorial I managed to create a label that does this. but still has a problem. The problem is that the label is not sized enough to show all the text. Put simply it seems that it calculates the size of the label regardless of the size of the ruby annotation.
How do I solve the problem?
Please help me because I’m near to solution
thank you very much
Attached you will find a project with all the code. just run it to see the code in action with the problem.
RubyTest.zip (62.2 KB)
In addition to this I place here the code of the label.
override func draw(_ rect: CGRect) {
var lineHeight: CGFloat { self.font.pointSize * 1.0 }
//super.draw(rect)
// context allows you to manipulate the drawing context (i'm setup to draw or bail out)
guard let context: CGContext = UIGraphicsGetCurrentContext() else {
return
}
// Flip the coordinate system
context.textMatrix = CGAffineTransform.identity;
context.translateBy(x: 0, y: self.bounds.size.height);
context.scaleBy(x: 1.0, y: -1.0);
let path = CGMutablePath()
let newRect = CGRect(x: self.bounds.origin.x, y: self.bounds.origin.y, width: self.bounds.size.width, height: self.bounds.size.height + 10)
path.addRect(self.bounds)
guard let str = self.attributedText else { return }
let frameSetter = CTFramesetterCreateWithAttributedString(str)
let frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0,str.length), path, nil)
// Check need for truncate tail
if (CTFrameGetVisibleStringRange(frame).length as Int) < str.length {
// Required truncate
let linesNS: NSArray = CTFrameGetLines(frame)
let linesAO: [AnyObject] = linesNS as [AnyObject]
var lines: [CTLine] = linesAO as! [CTLine]
let boundingBoxOfPath = path.boundingBoxOfPath
let lastCTLine = lines.removeLast()
let truncateString:CFAttributedString = CFAttributedStringCreate(nil, "\u{2026}" as CFString, CTFrameGetFrameAttributes(frame))
let truncateToken:CTLine = CTLineCreateWithAttributedString(truncateString)
let lineWidth = CTLineGetTypographicBounds(lastCTLine, nil, nil, nil)
let tokenWidth = CTLineGetTypographicBounds(truncateToken, nil, nil, nil)
let widthTruncationBegins = lineWidth - tokenWidth
if let truncatedLine = CTLineCreateTruncatedLine(lastCTLine, widthTruncationBegins, .end, truncateToken) {
lines.append(truncatedLine)
}
var lineOrigins = Array<CGPoint>(repeating: CGPoint.zero, count: lines.count)
CTFrameGetLineOrigins(frame, CFRange(location: 0, length: lines.count), &lineOrigins)
for (index, line) in lines.enumerated() {
context.textPosition = CGPoint(x: lineOrigins[index].x + boundingBoxOfPath.origin.x, y:lineOrigins[index].y + boundingBoxOfPath.origin.y)
CTLineDraw(line, context)
}
}
else {
// Not required truncate
CTFrameDraw(frame, context)
}
}