为什么从Float投射的CGFloat不显示CGFloat行为?

时间:2019-03-02 10:12:18

标签: swift casting drawing

我有一个简单的示例,尝试绘制一个圆。下面的这段代码不会给我一个圆圈。

import UIKit

class PlayingCardView: UIView {

    override func draw(_ rect: CGRect) {
        if let context = UIGraphicsGetCurrentContext(){

            context.addArc(center: CGPoint(x: bounds.midX, 
                           y: bounds.midY), radius: 100.0, 
                           startAngle: 0, 
                           endAngle: CGFloat(2.0*Float.pi), 
                           clockwise: true)

            context.setLineWidth(5.0)
            UIColor.red.setStroke()
            context.strokePath()
            print(2.0*CGFloat.pi)
            print(CGFloat(2.0*Float.pi))
        } 
    }
}

is what I get与上面的代码:

输出:

6.283185307179586 6.283185005187988

分别对应于2.0*CGFloat.piCGFloat(2.0*Float.pi)的打印语句。

将代码更新为此(我仅将context.addArc中的endAngle更改为2.0*CGFloat.pi而不是CGFloat(2.0*Float.pi)

import UIKit

class PlayingCardView: UIView {

    override func draw(_ rect: CGRect) {
        if let context = UIGraphicsGetCurrentContext(){

            context.addArc(center: CGPoint(x: bounds.midX, 
                           y: bounds.midY), radius: 100.0, 
                           startAngle: 0, 
                           endAngle: 2.0*CGFloat.pi, 
                           clockwise: true)

            context.setLineWidth(5.0)
            UIColor.red.setStroke()
            context.strokePath()
            print(2.0*CGFloat.pi)
            print(CGFloat(2.0*Float.pi))
        } 
    }
}

我得到了这个drawing(圆圈在那里)

从Float铸造的CGFloat与CGFloat之间显然存在差异。有人知道它是什么,为什么这种行为在Swift中有用?

1 个答案:

答案 0 :(得分:3)

在64位平台上,CGFloat(基本上)是Double,是64位浮点数,而Float是32位浮点数。

因此2.0*Float.pi是“具有32位精度的2π”,并将其转换为64位量CGFloat会保留该值,而不会提高精度。

这就是2.0*CGFloat.pi != CGFloat(2.0*Float.pi)的原因。前者是“具有64位精度的2π”,是传递给绘图函数的内容。

在您的特定情况下,CGFloat(2.0*Float.pi)2.0*CGFloat.pi小一点,因此只绘制了无形的短弧(从弧度0.0到大约-0.00000003)。

对于整圈,您也可以使用

let radius: CGFloat = 100.0
context.addEllipse(in: CGRect(x: bounds.midX - radius, y: bounds.midY - radius,
                              width: 2.0 * radius, height: 2.0 * radius))

并避免所有舍入问题。