用作TableView数据源的Swift通用枚举

时间:2018-05-23 09:01:48

标签: ios swift enums

我想创建一个UITableViewController,它接受enum作为它的数据源。 问题是,我有很多enums我希望它能够处理。

我创建了一个名为TableViewSelectable的协议,并创建了一些符合它的enums,如下所示:

protocol TableViewSelectable {

}

enum Genders: Int, TableViewSelectable {
    case male = 0, female

    static let allKeys = [male, female]
    static let allNames = [male.getName, female.getName]

    var getName: String {
        switch self {
        case .male:
            return "Male"
        case .female:
            return "Female"
        }
    }
}

enum Goals: Int, TableViewSelectable {
    case gainMuscleMass, getTrimFit, loseWeight

    static let allKeys = [gainMuscleMass, getTrimFit, loseWeight]
    static let allNames = [gainMuscleMass.getName, getTrimFit.getName, loseWeight.getName]

    var getName: String {
        switch self {
        case .gainMuscleMass:
            return "Gain muscle mass"
        case .getTrimFit:
            return "Get trim & fit"
        case .loseWeight:
            return "Lose weight"
        }
    }
}

我在我的UITableViewController上创建了一个实例变量,如下所示:

class ChoiceListTableViewController: UITableViewController {

    var data: TableViewSelectable?

}

问题是我不知道该如何离开这里。 我想要的是为UITableViewController enum提供符合​​TableViewSelectable的{​​{1}}以便用作其数据源的选项。

我希望像UITableViewController这样访问它:

final class ChoiceListTableViewController: UITableViewController {

    var data: TableViewSelectable?


    // MARK: Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()
        self.clearsSelectionOnViewWillAppear = false
    }

}

// MARK: Table View Data Source & Delegate

extension ChoiceListTableViewController {

    override func numberOfSections(in tableView: UITableView) -> Int {

        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return data.allKeys.count
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "ChoiceTableViewCell", for: indexPath)

        cell.textLabel?.text = data.allNames[indexPath.row]

        return cell
    }

}

请帮忙吗? :)

1 个答案:

答案 0 :(得分:0)

您当前实施的问题是您应在allKeys方法中使用的allNamesUITableViewDataSource静态属性不属于TableViewSelectable协议,因此您无法使用data变量访问它们。

您应该修改协议以包含这些协议。

protocol TableViewSelectable {
    static var allKeys: [TableViewSelectable] {get}
    static var allNames: [String] {get}
}

您还需要相应地修改符合它的enum

enum Genders: Int, TableViewSelectable {
    case male = 0, female

    static let allKeys:[TableViewSelectable] = [male, female]
    static let allNames = [male.getName, female.getName]

    var getName: String {
        switch self {
        case .male:
            return "Male"
        case .female:
            return "Female"
        }
    }
}

enum Goals: Int, TableViewSelectable {
    case gainMuscleMass, getTrimFit, loseWeight

    static let allKeys:[TableViewSelectable] = [gainMuscleMass, getTrimFit, loseWeight]
    static let allNames = [gainMuscleMass.getName, getTrimFit.getName, loseWeight.getName]

    var getName: String {
        switch self {
        case .gainMuscleMass:
            return "Gain muscle mass"
        case .getTrimFit:
            return "Get trim & fit"
        case .loseWeight:
            return "Lose weight"
        }
    }
}

然后,您只需使用data.allKeysdata.allNames即可访问数据源方法中这些数组的相应元素。

class ChoiceListTableViewController: UITableViewController {
    var data:TableViewSelectable.Type! // make sure that this is actually initialized before accessing it

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.allKeys.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "id", for: indexPath)
        cell.textLabel?.text = data.allNames[indexPath.row]
        return cell
    }
}