Display japanese Text with furigana in UILabel

前端 未结 3 511
天涯浪人
天涯浪人 2021-01-07 09:02

for my app, few month ago, i\'ve take the code from this site to use CTRubyAnnotation.

This code, with few changes to make work with swift 4, work perfectly.

3条回答
  •  我在风中等你
    2021-01-07 09:05

    I have same issue.
    Your code as Swift4 works correctly on iOS10. It does not function correctly on iOS11.
    It seems that there was a change in NSAttributedString of UILabel on iOS 11.
    I wrote a general program to draw vertical writing characters in CoreText before. In CoreText, NSAttributedString works on iOS11 as well. Although it is a provisional method, you can avoid this problem by using CoreText.
    I written sample code. Since this draws characters directly to context, there is no need for UILabel, but draw with UILabel 's drawText for the moment.

    import UIKit
    
    protocol SimpleVerticalGlyphViewProtocol {
    }
    
    extension SimpleVerticalGlyphViewProtocol {
    
        func drawContext(_ attributed:NSMutableAttributedString, textDrawRect:CGRect, isVertical:Bool) {
    
            guard let context = UIGraphicsGetCurrentContext() else { return }
    
            var path:CGPath
            if isVertical {
                context.rotate(by: .pi / 2)
                context.scaleBy(x: 1.0, y: -1.0)
                path = CGPath(rect: CGRect(x: textDrawRect.origin.y, y: textDrawRect.origin.x, width: textDrawRect.height, height: textDrawRect.width), transform: nil)
            }
            else {
                context.textMatrix = CGAffineTransform.identity
                context.translateBy(x: 0, y: textDrawRect.height)
                context.scaleBy(x: 1.0, y: -1.0)
                path = CGPath(rect: textDrawRect, transform: nil)
            }
    
            let framesetter = CTFramesetterCreateWithAttributedString(attributed)
            let frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attributed.length), path, nil)
    
            CTFrameDraw(frame, context)
        }
    }
    

    And, Use it like below.

    import UIKit
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var furiganaLabel: CustomLabel!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            furiganaLabel.attributedText = Utility.sharedInstance.furigana(String: "|優勝《ゆうしょう》の|懸《か》かった|試合《しあい》。")
        }
    }
    
    class CustomLabel: UILabel, SimpleVerticalGlyphViewProtocol {
        //override func draw(_ rect: CGRect) { // if not has drawText, use draw UIView etc
        override func drawText(in rect: CGRect) {
            let attributed = NSMutableAttributedString(attributedString: self.attributedText!)
            let isVertical = false // if Vertical Glyph, true.
            attributed.addAttributes([NSAttributedStringKey.verticalGlyphForm: isVertical], range: NSMakeRange(0, attributed.length))
            drawContext(attributed, textDrawRect: rect, isVertical: isVertical)
        }
    }
    

    I added the CustomLabel class which adapted SimpleVerticalGlyphViewProtocol.
    Please set the CustomLabel class as UILabel 's Custom Class on Storyboard.

    Font size auto scale, and specify line number 0

    Fixed font size, specify line number 4, baseline alignCenters, and last line truncated.

    Font size auto scale, and specify line number 0 with Ruby

提交回复
热议问题