如果枚举作为参数,你如何从func返回不同的uibutton子类?

时间:2017-03-25 17:12:07

标签: ios swift generics casting

所以下面我已经包含了一些代码。这段代码显然无法编译。当我尝试将子类类型转换为UIButton类型时,错误读取Expected member name or constructor call after type name

我希望能够在我的AppDelegate中调用此按钮func,以便我可以更改该类型的UIAppearance。这就是我返回类型而不是实例的原因。所以,如果我不能使用演员,我应该尝试使用泛型,还是我在想这个问题都错了?任何见解都表示赞赏。无论如何,我只是想知道如何选择一个特定类型的按钮,这样我就可以设置它的风格,无论是使用泛型还是铸造都可以做到这一点。

enum BtnType : Int {
    case Primary
    case Secondary
}

func button(type: BtnType) -> UIButton.Type {
    var button: UIButton.Type

    switch type {
        case .Primary:
            button = PrimaryButton.Type as! UIButton.Type
        case .Secondary:
            button = SecondaryButton.Type as! UIButton.Type
        default:
            button = PrimaryButton.Type as! UIButton.Type
    }

    return button
}

1 个答案:

答案 0 :(得分:1)

在自定义按钮类型上使用self可返回相应的元类型(类型为Button.Type):

func buttonType(for type: BtnType) -> UIButton.Type {
    let button: UIButton.Type
    switch type {
    case .Primary: button = PrimaryButton.self
    case .Secondary: button = SecondaryButton.self
    }
    return button
}

请注意,您可以说let button: UIButton.Type(而不是var)因为它在switch中设置了一次。

另请注意,您不需要投放as! UIButton.Type,因为AnyButtonSubclass.selfUIButton.Type

使用示例:

let b = buttonType(for: .Primary).init(type: .system) // b is a UIButton
b.setTitle("Primary", for: .normal)

关于.Type.self

(我只是坚持这里的课程而不是进入编译时类型而不是运行时类型以保持简单。)

您可能习惯使用对象和类。对象是类的实例。对象的类型是对象是其实例的类。高一级(因此是元), 你正在处理类和元类。这里,类的类型是它的元类。

从语法上讲,只要您需要或想要写一个类型,就可以说Foo.Type。这可以是变量的类型,参数的类型,或者在这种情况下,是buttonType(for:)的返回类型。 UIButton.selfUIButton.Type类型的表达式。就像您可以将UIButton实例分配给UIButton类型的变量一样,您可以将UIButton.self分配给UIButton.Type的变量。

请注意,在两个级别(对象和类,类和元类)上,您都有一个" is-a"关系。您可以将UIButton的任何子类的实例分配给类型为UIButton的变量。 同样,您可以将任何SubclassOfUIButton.self分配给UIButton.Type

变量

一些有希望的说明性代码:

class PrimaryButton: UIButton { ... }
class SecondaryButton: UIButton { ... }

let button = PrimaryButton(type: .system)
button is PrimaryButton  // true
button is UIButton  // true
button is UIControl  // true
// etc
button is String  // false
let uibutton: UIButton = button

let buttonType: PrimaryButton.Type = PrimaryButton.self
buttonType is PrimaryButton.Type  // true
buttonType is UIButton.Type  // true
buttonType is UIControl.Type  // true
// etc
buttonType is String.Type  // false
let uiButtonType: UIButton.Type = buttonType