ios swift核心图形-字符串颠倒

标签 ios swift string core-graphics

当我想在 CGContext 中绘制一个 String 时,文本显示颠倒了。

我知道这个主题已经发布在这里,但没有一个解决方案对我有用。

我确实翻转了上下文:

graphContext.scaleBy(x: 1.0, y: -1.0)
graphContext.translateBy(
        x: CGFloat(0.0),
        y: CGFloat(-1.0 * graphSize.h))

我也尝试对 textMatrix 做同样的事情,但这对结果没有任何影响。

完整的项目资源在这里:dropbox 屏幕截图在这里:screen shot

不知道为什么它不起作用。

谢谢

我的绘制方法:

override func draw(_ rect: CGRect) {

        let graphSize = GSize(
            w: Double(self.frame.width),
            h: Double(self.frame.height))

        rebaseAreas(graphSize: graphSize)

        graphContext = UIGraphicsGetCurrentContext()!
        graphContext.saveGState()

        // Flip the context coordinates, in iOS only
        graphContext.scaleBy(x: 1.0, y: -1.0)
        graphContext.translateBy(
            x: CGFloat(0.0),
            y: CGFloat(-1.0 * graphSize.h))


        // this has no effect, I can delete it and nothing changes
        graphContext.textMatrix = CGAffineTransform(scaleX: 2.0, y: -2.0)


        drawBackground(
            inRect: graph_drawing_rect,
            inContext: graphContext)


        drawGuidelines(
            vAxis: vAxis,
            hAxis: hAxis,
            inRect: serie_drawing_rect,
            inContext: graphContext)


        drawSerie(
            points,
            inRect: serie_drawing_rect,
            inContext: graphContext)


        drawTitle(
            inRect: graph_drawing_rect,
            inContext: graphContext)


        drawVAxisLabels(
            vAxis: vAxis,
            inRect: x_labels_drawing_rect,
            inContext: graphContext)


        drawHAxisLabels(
            hAxis: hAxis,
            inRect: y_labels_drawing_rect,
            inContext: graphContext)

        graphContext.restoreGState()
    }

还有我的 drawTitle 方法:

func drawTitle(
        inRect rect: GRect,
        inContext context: CGContext) {

        // saving the calling state
        context.saveGState()

        let title = titleLabelText

        let lblAttributes = [
            NSFontAttributeName: titleFont,
            NSForegroundColorAttributeName: title_font_color,
            ] as [String : Any]

        let origin = CGPoint(
            x: title_label_position.x * rect.w,
            y: title_label_position.y * rect.h)

        let drawRect = CGRect(
            origin: origin,
            size: title.size(attributes: lblAttributes))

        title.draw(
            in: drawRect,
            withAttributes: lblAttributes)

        // returning the calling state
        graphContext.restoreGState()
    }

最佳答案

您正在使用 UIKit 的字符串绘制支持。 UIKit 将您正在使用的方法 drawInRect:withAttributes: 添加到 NSString

UIKit 在绘制字符串时设置文本矩阵。 (您可以在 CGContextSetTextMatrix 上设置断点来验证这一点。)这意味着您尝试设置 textMatrix 无效。

UIKit 期望图形上下文的原点位于绘图区域的左上角,并且它期望 y 坐标向绘图区域的底部增加。您已经翻转了 y 轴的方向,因此 UIKit 最终将文本倒置绘制。

由于您无法使用文本矩阵修复此问题,因此您必须使用转换矩阵来修复它。您需要将原点平移到应该包含文本的矩形的左上角,翻转y轴,在原点绘制文本,然后恢复变换矩阵。

您可以将其包装在 NSString 的扩展方法中:

private extension String {

    func drawFlipped(in rect: CGRect, withAttributes attributes: [String: Any]) {
        guard let gc = UIGraphicsGetCurrentContext() else { return }
        gc.saveGState()
        defer { gc.restoreGState() }
        gc.translateBy(x: rect.origin.x, y: rect.origin.y + rect.size.height)
        gc.scaleBy(x: 1, y: -1)
        self.draw(in: CGRect(origin: .zero, size: rect.size), withAttributes: attributes)
    }

}

然后您可以使用您的扩展方法代替 draw(in:withAttributes:)。例如,这是您的 drawTitle(inRect:inContext:) 方法的替代品:

func drawTitle(
    inRect rect: GRect,
    inContext context: CGContext) {

    let title = titleLabelText

    let lblAttributes = [
        NSFontAttributeName: titleFont,
        NSForegroundColorAttributeName: title_font_color,
        ] as [String : Any]

    let origin = CGPoint(
        x: title_label_position.x * rect.w,
        y: title_label_position.y * rect.h)

    let drawRect = CGRect(
        origin: origin,
        size: title.size(attributes: lblAttributes))

    title.drawFlipped(in: drawRect, withAttributes: lblAttributes)
}

结果:

screen shot with correctly drawn title

请注意,我只修复了 drawTitle(inRect:inContext:),因此所有其他文本仍然是颠倒的。

关于ios swift核心图形-字符串颠倒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44122778/

相关文章:

ios - 在 iOS 上禁用 'Don' t Reopen' 或 'Reopen' 对话框

iphone - 向 UILabel 添加背景图像

Swift/UIView/drawrect - 如何在需要时更新 drawrect

ios - 使用 iOS 图表将图片保存到相机胶卷

c++ - 非 POD 元素类型的可变长度数组 'string'(又名 'basic_string<char>')c++

ios - Swift 类对象在调用函数时发送它的值

ios - 在 Xcode (6.1) 中设置文本样式

ios - 如何使用 Swift 制作简单的 Collection View

c++ - 通过迭代器进行 basic_string 转换是否合法?

javascript - 如何解决 Javascript 中字符串的不变性问题?