Ios 如果给定一个枚举作为参数,如何从func返回不同的uibutton子类?

Ios 如果给定一个枚举作为参数,如何从func返回不同的uibutton子类?,ios,swift,generics,casting,Ios,Swift,Generics,Casting,下面我已经包含了我的一些代码。这段代码显然是不可编译的。当我尝试将我的子类类型强制转换为UIButton类型时,错误读取类型名称之后的预期成员名称或构造函数调用 我希望能够在AppDelegate中调用此按钮func,以便更改类型的外观。这就是我返回类型而不是实例的原因。所以,如果我不能使用cast,我应该尝试使用泛型,还是我对这个问题的想法都错了?任何见解都将不胜感激。无论如何,我只是想知道如何选择一种特定类型的按钮,这样我就可以设计它的样式,无论是否有一种方法可以使用泛型或强制转换 enum

下面我已经包含了我的一些代码。这段代码显然是不可编译的。当我尝试将我的子类类型强制转换为UIButton类型时,错误读取类型名称之后的
预期成员名称或构造函数调用

我希望能够在AppDelegate中调用此按钮func,以便更改类型的外观。这就是我返回类型而不是实例的原因。所以,如果我不能使用cast,我应该尝试使用泛型,还是我对这个问题的想法都错了?任何见解都将不胜感激。无论如何,我只是想知道如何选择一种特定类型的按钮,这样我就可以设计它的样式,无论是否有一种方法可以使用泛型或强制转换

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
}

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

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

还请注意,您不需要将
强制转换为!UIButton.Type
是因为
AnyButtonSubclass.self
是一个
UIButton.Type

用法示例:

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

(这里我只讨论类,不讨论编译时类型和运行时类型,以使事情更简单。)

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

从语法上讲,无论何时需要或想要编写类型,都可以说
Foo.type
。这可以是变量、参数的类型,也可以是
按钮类型(for:)
的返回类型。
UIButton.self
是类型为
UIButton.type
的表达式。就像您可以将
UIButton
实例分配给
UIButton
类型的变量一样,您也可以将
UIButton.self
分配给
UIButton.type
类型的变量

请注意,在这两个级别(对象和类、类和元类)上,都有“is-a”关系。您可以将
UIButton
的任何子类的实例分配给
UIButton
类型的变量。 同样,您可以将任何
子类subassofuibutton.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

您希望函数返回所需的按钮类型,还是该类型的新实例?创建该类型的新实例似乎更有用。我希望它返回按钮类型,因为我将执行此操作
PrimaryButton.appearance().backgroundColor=“任意颜色”
,所以在实例化任何PrimaryButton之前都会执行此操作。不过,如果您还有其他工作,请随时与我们分享。谢谢!正是我想要的。那么为什么我不能使用类型呢?我甚至尝试过
.type.type
,当我注意到自动完成提供了这样做的选项时。我想
.self
是有意义的,因为它还没有被实例化,所以它一定是引用类本身,但我认为这有点让人困惑,因为
UIButton.type
是有效的。我相信你也可以在UIButton上使用
.self
,然后不受惩罚。稍后我会更新我的答案,以进一步解释这些问题。注意,我不应该调用makeButton方法,因为它实际上并不生成一个,而是返回生成一个的类型。我也会更新它。@user3832583:我重命名了该函数并添加了“About.Type和.self”部分。我希望这能把事情弄清楚。
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