100
CGFloat 2016/9/28 Hirohito Kato

Fighting history of CGFloat in Swift

Embed Size (px)

Citation preview

CGFloat2016/9/28 Hirohito Kato

• CGFloat

• Swift

CGFloat

• Core Graphics

• SpriteKit/SceneKit UIKit

CGFloat

• double / float typedef

• CPU

• double

• CGFloat

• NSNumber CGFloat

• double

• iOS iPhone5 or iPhone5S

…double

20XX Swift

CGFloat

CGFloat ≠ Float

CGFloat ≠ Double

CGFloat “is” CGFloat

let value1: CGFloat = 240 // OK

let value1: CGFloat = 240 // OK

let value2: CGFloat = 80.0 // OK

let a = CGFloat(10)

let a = CGFloat(10)let b = 30

let a = CGFloat(10)let b = 30

let value = a + b // ERROR!

let a = CGFloat(10)let b = 30

let value = a + b // ERROR!

let value = a + CGFloat(b) // OK

let pos = CGPoint(x: 160, y: 80.0)

let pos = CGPoint(x: 160, y: 80.0)// OK

let pos = CGPoint(x: 160, y: 80.0)// OK

let a = 160

let pos = CGPoint(x: 160, y: 80.0)// OK

let a = 160let pos = CGPoint(x: a, y: 80.0)

let pos = CGPoint(x: 160, y: 80.0)// OK

let a = 160let pos = CGPoint(x: a, y: 80.0)// ERROR!

let pos = CGPoint(x: 160, y: 80.0)// OK

let a = 160let pos = CGPoint(x: a, y: 80.0)// ERROR!

let x = 32

let x = 32let y = 120.0

let x = 32let y = 120.0let w = Float(44.0)

let x = 32let y = 120.0let w = Float(44.0)let h = CGFloat(24)

let x = 32let y = 120.0let w = Float(44.0)let h = CGFloat(24)

view.rect = CGRect(x: x,

let x = 32let y = 120.0let w = Float(44.0)let h = CGFloat(24)

view.rect = CGRect(x: x, y: y,

let x = 32let y = 120.0let w = Float(44.0)let h = CGFloat(24)

view.rect = CGRect(x: x, y: y, width: w,

let x = 32let y = 120.0let w = Float(44.0)let h = CGFloat(24)

view.rect = CGRect(x: x, y: y, width: w, height: h)

let x = 32let y = 120.0let w = Float(44.0)let h = CGFloat(24)

view.rect = CGRect(x: x, y: y, width: w, height: h)// ERROR!

let x = 32let y = 120.0let w = Float(44.0)let h = CGFloat(24)

view.rect = CGRect(x: x, y: y, width: w, height: h)// ERROR!

let x = 32

let x = 32let y = 120.0

let x = 32let y = 120.0let w = Float(44.0)

let x = 32let y = 120.0let w = Float(44.0)let h = CGFloat(24)

let x = 32let y = 120.0let w = Float(44.0)let h = CGFloat(24)

view.rect = CGRect(x: CGFloat(x),

let x = 32let y = 120.0let w = Float(44.0)let h = CGFloat(24)

view.rect = CGRect(x: CGFloat(x), y: CGFloat(y),

let x = 32let y = 120.0let w = Float(44.0)let h = CGFloat(24)

view.rect = CGRect(x: CGFloat(x), y: CGFloat(y), width: CGFloat(w),

let x = 32let y = 120.0let w = Float(44.0)let h = CGFloat(24)

view.rect = CGRect(x: CGFloat(x), y: CGFloat(y), width: CGFloat(w), height: h)

let x = 32let y = 120.0let w = Float(44.0)let h = CGFloat(24)

view.rect = CGRect(x: CGFloat(x), y: CGFloat(y), width: CGFloat(w), height: h)// OK

let x = 32let y = 120.0let w = Float(44.0)let h = CGFloat(24)

view.rect = CGRect(x: CGFloat(x), y: CGFloat(y), width: CGFloat(w), height: h)// OK

• Swift Objective-C

Float/Double CGFloat

• /

• …

CGFloat

Float Double=

extension Double { var cgf:CGFloat { return CGFloat(self) } }

let y = 1 + 10.0.cgf // OK, yay!

extension Double { var cgf:CGFloat { return CGFloat(self) } } extension Int { var cgf:CGFloat { return CGFloat(self) } } extension Float { var cgf:CGFloat { return CGFloat(self) } }

extension Double {var c:CGFloat { return CGFloat(self) }

}extension Int {

var c:CGFloat { return CGFloat(self) }}extension Float {

var c:CGFloat { return CGFloat(self) }}extension Float80 {

var c:CGFloat { return CGFloat(self) }}extension UInt {

var c:CGFloat { return CGFloat(self) }}extension UInt8 {

var c:CGFloat { return CGFloat(self) }}extension UInt16 {

var c:CGFloat { return CGFloat(self) }}extension UInt32 {

var c:CGFloat { return CGFloat(self) }}

extension UInt64 {var c:CGFloat { return CGFloat(self) }

}extension Int8 {

var c:CGFloat { return CGFloat(self) }}extension Int16 {

var c:CGFloat { return CGFloat(self) }}extension Int32 {

var c:CGFloat { return CGFloat(self) }}extension Int64 {

var c:CGFloat { return CGFloat(self) }}extension UInt64 {

var c:CGFloat { return CGFloat(self) }}extension MyNumberType {

var c:CGFloat { return CGFloat(self) }}extension MyNumberTypeB {

var c:CGFloat { return CGFloat(self) }}

:

• …

Swift

OK

let a: Float = 190.0 let b: Int = 3 let value = CGFloat(a) + CGFloat(b)

CGFloat

public struct CGFloat { public init() public init(_ value: Float) public init(_ value: Double) public init(_ value: Float80) public init(_ value: CGFloat) public init(_ value: UInt8) public init(_ value: Int8) :

• CGFloat

• Int

Protocol

Protocol =

• API

• Java/C# Interface Ruby mix-in C++

• ( ) protocol

• extension

• /protocol

extension Int: MyCustomProtocol {}

Swift protocol

Swift protocol

• init

protocol CGFConvertible { init (_ value: Int) init (_ value: Float) init (_ value: Double) init (_ value: CGFloat) } // extension Int: CGFConvertible {} extension Float: CGFConvertible {} extension Double: CGFConvertible {} extension CGFloat: CGFConvertible {}

Generic

CGFConvertible

T

… Swift

extension CGFConvertible { fileprivate func convert <T: CGFConvertible>() -> T { return T(self) } }

func checkType<T>(_ x: T) { switch x { case _ as CGFloat: print("\(x) is a CGFloat") case _ as Float: print("\(x) is a Float") case _ as Int: print("\(x) is a Int") case _ as Double: print("\(x) is a Double") default: print("\(x) is unknown..") } }

Swift Workaround

RTTI

extension CGFConvertible { fileprivate func convert<T: CGFConvertible>() -> T { switch self { case let x as CGFloat: return T(x) case let x as Float: return T(x) case let x as Int: return T(x) case let x as Double: return T(x) default: fatalError("Unsupported format") } } public var c: CGFloat { return convert() } }

K

• CGFloat

• Int,Float,Double

let value: Double = Double(CGFloat(3) + 5.cgf)

• / …

let a = CGFloat(10) let b = 30

let value = a + b // ERROR! let value = a + 3.14 // ERROR!

CGFConvertible

CGFConvertible

Double…

let a = 3 let x: CGFloat = a + CGFloat(4.2) // OK let y: CGFloat = a * 4.2 // OK, yay!

extension CGFConvertible { private typealias CombineType = (Double,Double) -> Double fileprivate func operate<T:CGFConvertible, V:CGFConvertible> (b:T, combine: CombineType) -> V { let x:Double = self.convert() let y:Double = b.convert() return combine(x,y).convert() } }

func + <T:CGFConvertible, U:CGFConvertible,V:CGFConvertible> (lhs: T, rhs: U) -> V { return lhs.operate(b: rhs, combine: + ) } func - <T:CGFConvertible, U:CGFConvertible,V:CGFConvertible> (lhs: T, rhs: U) -> V { return lhs.operate(b: rhs, combine: - ) }

a.

protocol CGFConvertible { init (_ value: Int) init (_ value: Float) init (_ value: Double) init (_ value: CGFloat) }

extension Int: CGFConvertible {} extension Float: CGFConvertible {} extension Double: CGFConvertible {} extension CGFloat: CGFConvertible {}

extension CGFConvertible { fileprivate func convert<T: CGFConvertible>() -> T { return T(x) } }

b.

extension CGFConvertible { private typealias CombineType = (Double,Double) -> Double fileprivate func operate<T:CGFConvertible, V:CGFConvertible> (b:T, combine: CombineType) -> V { let x:Double = self.convert() let y:Double = b.convert() return combine(x,y).convert() } } func + <T:CGFConvertible, U:CGFConvertible,V:CGFConvertible> (lhs: T, rhs: U) -> V { return lhs.operate(b: rhs, combine: + ) } func - <T:CGFConvertible, U:CGFConvertible,V:CGFConvertible> (lhs: T, rhs: U) -> V { return lhs.operate(b: rhs, combine: - ) } func * <T:CGFConvertible, U:CGFConvertible,V:CGFConvertible> (lhs: T, rhs: U) -> V { return lhs.operate(b: rhs, combine: * ) }

let a = 3 let x: CGFloat = a + CGFloat(4.2) // OK let y: CGFloat = a * 4.2 // OK, yay!

CGFloat ≠ Float/Double/…

• Objective-C

• /

• Swift