Swift实现LiteralConvertible协议

时间:2014-10-22 00:04:06

标签: swift

我试图在UIColor上实现IntegerLiteralConvertible协议。我真正想做的就是这个

 let black: UIColor = 0x000000

我首先尝试按照这里的快速博客https://developer.apple.com/swift/blog/?id=8开箱即用。似乎根据swift in flux https://github.com/ksm/SwiftInFlux#literalconvertible-protocols-use-constructor,他们不再使用convertFromIntegerLiteral而是使用初始化器。因此,这就是我们应该拥有的:

extension UIColor: IntegerLiteralConvertible {
    public convenience init(integerLiteral value: IntegerLiteralType) {
    UIColor(red: 1, green: 0, blue: 0, alpha: 1)
    }
}

但那么初始化器内部会发生什么?我不能自我设定。我想说点什么

self.init(red: 0, green: 0, blue: 0, alpha: 1)

它不起作用,似乎也没有做任何其他事情。我得到错误"初始化程序要求init(IntegerLiteral)只能通过“必需”来满足。初始化者在非最终类别的定义中“UIColor' "这不是很有帮助。关于如何使这项工作的任何想法?

4 个答案:

答案 0 :(得分:2)

以下是Swift 2.0的(变通方法)代码:

public class Color: UIColor, IntegerLiteralConvertible {

    public typealias IntegerLiteralType = UInt32

    public required init(integerLiteral value: IntegerLiteralType) {

        let a = CGFloat((value & 0xFF000000) >> 24) / 255.0
        let r = CGFloat((value & 0xFF0000) >> 16) / 255.0
        let g = CGFloat((value & 0xFF00) >> 8) / 255.0
        let b = CGFloat((value & 0xFF)) / 255.0

        super.init(red: r, green: g, blue: b, alpha: a)
    }

    required public init(colorLiteralRed red: Float, green: Float, blue: Float, alpha: Float) {

        super.init(red: CGFloat(red), green: CGFloat(green), blue: CGFloat(blue), alpha: CGFloat(alpha))
    }

    required public init?(coder aDecoder: NSCoder) {

        super.init(coder: aDecoder)
    }
}

答案 1 :(得分:1)

如果你只是写

let black = 0x000000

Swift无法知道您想要定义颜色。只有一个字面十六进制数字,因此black只是一个按类型推断的整数。

也许你正在寻找像

这样的东西
let black : UIColor = 0x000000

但我认为你的方式可能会不必要地复杂化。最自然的方法是简单地编写一个带有int的初始化器。

extension UIColor {
    convenience init(_ hex: Int) {
        // add code to analyze the Int 
        // and generate appropriate r, g, b, as CGFloat
        return self.init(red: r, green: g, blue: b, alpha: 1)
    }
}

请注意参数名称前面的下划线,它允许您省略它。现在,您可以简洁地创建颜色:

let black = UIColor(0x000000)

答案 2 :(得分:1)

看起来考虑到Swift 1.1中的更改​​,这是不可能的。希望这会在将来的版本中发生变化。

https://devforums.apple.com/message/1057171#1057171

答案 3 :(得分:0)

不幸的是,在Swift 1.1中似乎唯一的解决方法是类扩展或结构组合:/

class MyColor : UIColor,  IntegerLiteralConvertible {
    required init(integerLiteral value: IntegerLiteralType) {
        //code to set values from int ...
        super.init(red: red, green: green, blue: blue, alpha: 1.0)
    }
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

var x:MyColor = 0x00FF00
println(x)