核心文本旋转没有正确旋转 - 斯威夫特

时间:2016-02-15 00:18:38

标签: ios swift macos core-graphics core-text

我正在尝试旋转Core Text,尽管它是通过旋转的上下文生成的,但它仍然可读。

我的问题是,无论旋转方法如何,结果文本都不是预期的。

这是工作场所:

import Foundation
import UIKit
import XCPlayground


class ClockFace: UIView {

    func drawText(context: CGContextRef, text: NSString, attributes: [String: AnyObject], x: CGFloat, y: CGFloat, align: CGFloat) -> CGSize {
        CGContextTranslateCTM(context, 0, 0)
        CGContextScaleCTM(context, 1, -1)
        let font = attributes[NSFontAttributeName] as! UIFont
        let attributedString = NSAttributedString(string: text as String, attributes: attributes)

        let textSize = text.sizeWithAttributes(attributes)

        let textPath    = CGPathCreateWithRect(CGRect(x: -x, y: y + font.descender, width: ceil(textSize.width), height: ceil(textSize.height)), nil)
        let frameSetter = CTFramesetterCreateWithAttributedString(attributedString)
        let frame       = CTFramesetterCreateFrame(frameSetter, CFRange(location: 0, length: attributedString.length), textPath, nil)
        CGContextSetTextMatrix(context, CGAffineTransformMakeRotation(align * 43.0))
        CTFrameDraw(frame, context)

        return textSize
    }

    override func drawRect(rect: CGRect) {
        let ctx: CGContext? = UIGraphicsGetCurrentContext()
        var nums: Int = 0
        for i in 0..<60 {
            CGContextSaveGState(ctx)
            CGContextTranslateCTM(ctx, rect.width / 2, rect.height / 2)
            CGContextRotateCTM(ctx, CGFloat(6.0 * Double(i) * M_PI / 180))
            if (i % 5 == 0) {
                nums++
                drawText(ctx!, text: "\(nums)", attributes: [NSForegroundColorAttributeName : UIColor.blackColor().CGColor, NSFontAttributeName : UIFont.systemFontOfSize(12)], x: 42, y: 0, align: CGFloat(6.0 * Double(i) * M_PI / 180))
            }
            CGContextRestoreGState(ctx)
        }

    }
}
let myView = ClockFace(frame: CGRectMake(0, 0, 150, 150))
myView.backgroundColor = .lightGrayColor()
XCPShowView("", view: myView)

无论CGAffineTransfomMakeRotation中的值如何,文字都难以辨认。

这是为什么?我正确地旋转文本吗?

问候,布兰登

1 个答案:

答案 0 :(得分:1)

我根据你的代码绘制了一个钟面,但稍微修改了一下。

基本上我所做的就是将整个钟面翻转并移动到for-loop之外。您可以看到我已将CGContextTranslateCTM()CGContextScaleCTM()drawText()移至drawRect()。由于上述修改,其他的是一些小的计算变化。

对于CGContextSetTextMatrix(),此处发生的旋转会影响每个字符但不影响整个字符串。你可以评论第19行&amp; 20,取消注释第21行,得到不同的结果,看看我的意思。

此外,如果您想直接获取操场文件,可以从here下载。

import Foundation
import UIKit
import XCPlayground


class ClockFace: UIView {

    func drawText(context: CGContextRef, text: String, attributes: [String: AnyObject], x: CGFloat, y: CGFloat, align: CGFloat) -> CGSize {
        let font = attributes[NSFontAttributeName] as! UIFont
        let attributedString = NSAttributedString(string: text, attributes: attributes)
        let textSize = text.sizeWithAttributes(attributes)

        let textPath    = CGPathCreateWithRect(CGRect(x: x, y: y + font.descender, width: ceil(textSize.width), height: ceil(textSize.height)), nil)
        let frameSetter = CTFramesetterCreateWithAttributedString(attributedString)
        let frame       = CTFramesetterCreateFrame(frameSetter, CFRange(location: 0, length: attributedString.length), textPath, nil)

        var transform = CGAffineTransformMakeTranslation(x + 10, y + font.descender)
        transform = CGAffineTransformRotate(transform, align)
        //CGContextSetTextMatrix(context, CGAffineTransformMakeRotation(align))
        CGContextConcatCTM(context, transform);
        CTFrameDraw(frame, context)

        return textSize
    }

    override func drawRect(rect: CGRect) {
        let ctx: CGContext? = UIGraphicsGetCurrentContext()
        CGContextTranslateCTM(ctx, -45, rect.size.height + 5)
        CGContextScaleCTM(ctx, 1, -1)
        var nums: Int = 2
        for i in 0..<60 {
            CGContextSaveGState(ctx)
            CGContextTranslateCTM(ctx, rect.width / 2, rect.height / 2)
            CGContextRotateCTM(ctx, CGFloat(-6.0 * Double(i) * M_PI / 180))
            if (i % 5 == 0) {
                nums++
                nums = nums > 12 ? nums - 12 : nums
                drawText(ctx!, text: "\(nums)", attributes: [NSForegroundColorAttributeName : UIColor.whiteColor(), NSFontAttributeName : UIFont.systemFontOfSize(12)], x: 42, y: 0, align: CGFloat(6.0 * Double(i) * M_PI / 180))

            }
            CGContextRestoreGState(ctx)
        }
    }
}

let view = ClockFace(frame: CGRectMake(0, 0, 150, 150))
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
XCPlaygroundPage.currentPage.liveView = view