CTRubyAnnotation不起作用

CTRubyAnnotation不起作用

本文介绍了Swift 4 CTRubyAnnotation不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我的应用程序,几个月前,我已经从这个网站获取代码使用CTRubyAnnotation。

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

此代码,几乎没有任何更改可以使用swift 4,完美地工作。

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

从这项工作我创建了一个类,我在其中编写了一个函数来使用该代码。

from this work I've create a class in which I written a function to use that code.

这是swift 4中的类

this is the class in swift 4

import UIKit

extension String {
    func find(pattern: String) -> NSTextCheckingResult? {
        do {
            let re = try NSRegularExpression(pattern: pattern, options: [])
            return re.firstMatch(
                in: self,
                options: [],
                range: NSMakeRange(0, self.utf16.count))
        } catch {
            return nil
        }
    }

    func replace(pattern: String, template: String) -> String {
        do {
            let re = try NSRegularExpression(pattern: pattern, options: [])
            return re.stringByReplacingMatches(
                in: self,
                options: [],
                range: NSMakeRange(0, self.utf16.count),
                withTemplate: template)
        } catch {
            return self
        }
    }
}



class Utility: NSObject {
    class var sharedInstance: Utility {
        struct Singleton {
            static let instance = Utility()
        }
        return Singleton.instance
    }

    func furigana(String:String) -> NSMutableAttributedString {
        let attributed =
            String
                .replace(pattern: "(|.+?《.+?》)", template: ",$1,")
                .components(separatedBy: ",")
                .map { x -> NSAttributedString in
                    if let pair = x.find(pattern: "|(.+?)《(.+?)》") {
                        let string = (x as NSString).substring(with: pair.range(at: 1))
                        let ruby = (x as NSString).substring(with: pair.range(at: 2))

                        var text: [Unmanaged<CFString>?] = [Unmanaged<CFString>.passRetained(ruby as CFString) as Unmanaged<CFString>, .none, .none, .none]
                        let annotation = CTRubyAnnotationCreate(CTRubyAlignment.auto, CTRubyOverhang.auto, 0.5, &text[0])

                        return NSAttributedString(
                            string: string,
                            attributes: [kCTRubyAnnotationAttributeName as NSAttributedStringKey: annotation])
                    } else {
                        return NSAttributedString(string: x, attributes: nil)
                    }
                }
                .reduce(NSMutableAttributedString()) { $0.append($1); return $0 }

        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineHeightMultiple = 1.5
        paragraphStyle.lineSpacing = 12
        attributed.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, (attributed.length)))
        attributed.addAttributes([NSAttributedStringKey.font: UIFont(name: "HiraMinProN-W3", size: 14.0)!, NSAttributedStringKey.verticalGlyphForm: false,],range: NSMakeRange(0, (attributed.length)))

        return attributed
    }

}

我不知道为什么但这段代码不起作用。

I don't know why but this code don't work.

这是班级使用此函数:

class ViewController: UIViewController {
    @IBOutlet weak var furiganaLabel: UILabel!
    override func viewDidLoad() {
        furiganaLabel.attributedText = Utility.sharedInstance.furigana(String: "|優勝《ゆうしょう》の|懸《か》かった|試合《しあい》。")

    }
}

这就是结果:

但原始代码完美无缺:

But with the original code work perfectly:Using original code

有人可以帮助我并解释原因吗?

Some one can help me and explain the reason?

非常感谢

推荐答案

我有同样的问题。

你的代码作为Swift4在iOS10上正常工作。它在iOS11上无法正常运行。

似乎在iOS 11上UILabel的NSAttributedString发生了变化。

我写了一个通用程序来在CoreText中绘制垂直书写字符。在CoreText中,NSAttributedString也适用于iOS11。
虽然它是一种临时方法,但您可以通过使用CoreText来避免此问题。

我编写了示例代码。由于这直接将字符绘制到上下文中,因此不需要UILabel,而是暂时使用UILabel的drawText进行绘制。

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)
    }
}

我添加了适应SimpleVerticalGlyphViewProtocol的CustomLabel类。

请设置CustomLabel类作为故事板上UILabel的自定义类。

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

字体大小自动缩放,并使用Ruby指定行号0

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

这篇关于Swift 4 CTRubyAnnotation不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!