为自定义类提供标准类型,但可以添加其他类型

时间:2018-10-26 13:06:38

标签: ios swift class types

我有一个协议(EasyPosTypes),其中包含应该能够分配给变量的所有类型。

protocol EasyPosTypes { }
protocol EasyPosStandardTypes { }

extension EPPercentage: EasyPosTypes { }
extension Int: EasyPosTypes, EasyPosStandardTypes { }
extension CGFloat: EasyPosTypes, EasyPosStandardTypes { }
extension Double: EasyPosTypes, EasyPosStandardTypes { }
extension Float: EasyPosTypes, EasyPosStandardTypes { }

然后我有了变量,x和y应该能够成为上面定义的类型(EasyPosTypes):

struct FrameComponent {
    var screenWidth = UIScreen.main.bounds.width
    var screenHeight = UIScreen.main.bounds.height

    var width: CGFloat = 0.0
    var height: CGFloat = 0.0

    var x: EasyPosTypes = 0.0
    var y: EasyPosTypes = 0.0
    var percentX: CGFloat = -1
    var percentY: CGFloat = -1
}

protocol EasyPos {
    var fc: FrameComponent { get set }
    func update()
}

在这里,我要测试类型。对于除EPPercent之外的所有代码,我都希望在if语句中运行代码,对于EPPercent,我要在else中的if上运行代码:

extension EasyPos where Self: UIView {
    func update() {
        if let xFloat = fc.x as? EasyPosStandardTypes {
            frame = CGRect(x: CGFloat(xFloat), y: frame.minY, width: frame.width, height: frame.height)
        } else if let xPercent = fc.x as? EPPercent {
            frame = CGRect(x: fc.screenWidth * CGFloat(xPercent) - frame.width / 2, y: frame.minY, width: frame.width, height: frame.height)
        }
    }
}

if中的代码给出以下错误:

  

“无法使用类型为((EasyPosStandardTypes)'的参数列表来调用类型为'CGFloat'的初始化程序”

else中的代码:

  

“无法使用类型为((EPPercent))的参数列表来调用类型为'CGFloat'的初始化程序”

1 个答案:

答案 0 :(得分:1)

您可以添加asCGFloat计算出的属性来修改协议

protocol EasyPosStandardTypes {
    var asCGFloat:  CGFloat { get }
}

extension Int: EasyPosTypes, EasyPosStandardTypes {
    var asCGFloat:  CGFloat { return CGFloat(self) }
}
extension CGFloat: EasyPosTypes, EasyPosStandardTypes {
    var asCGFloat:  CGFloat { return self }
}
extension Double: EasyPosTypes, EasyPosStandardTypes {
    var asCGFloat:  CGFloat { return CGFloat(self) }
}
extension Float: EasyPosTypes, EasyPosStandardTypes {
    var asCGFloat:  CGFloat { return CGFloat(self) }
} 

然后,当您需要从符合CGFloat协议的类型中获取EasyPosStandardTypes值时,可以使用此新属性。

if let xFloat = fc.x as? EasyPosStandardTypes {
    frame = CGRect(x: xFloat.asCGFloat, y: frame.minY, width: frame.width, height: frame.height)
} // ...