在变量中存储类型?

问题描述 投票:2回答:3

所以我想知道是否可以在变量中保存一个类型,稍后将在同一个函数中使用。

我的代码如下:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let object = array.item(at: indexPath.row) else {
        fatalError("Could not retrieve the table object")
    }

    if object.displayOnLeft {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: LeftSidedCell.className, for: indexPath) as? LeftSidedCell else {
            fatalError("Could not dequeue the left sided cell")
        }
        cell.object = object
        return cell
    } else {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: RightSidedCell.className, for: indexPath) as? RightSidedCell else {
             fatalError("Could not dequeue the right sided cell")
        }
        cell.object = object
        return cell
    }
}

但我认为这实际上非常笨重,因为if和else中的内容基本相同,只是单元格的类型不同。

我理想地想要一个基本上算法:

var type
if object.displayOnLeft {
   type = LeftSidedCell
} else {
   type = RightSidedCell
}

//Dequeue Cell with type

我知道这里有一些问题,首先,我不能声明一个没有类型的变量,并且我不确定首先将它分配给哪个类型。其次,检索类的类型也没有多少成果。

我已经尝试将它作为属性存储在Object中,并将其返回到我的自定义对象中的此类函数以及以下的一些变体:

func getTypeOfCell<T:TranslationCellProtocol>() -> T.Type {
    if displayOnLeft {
        return LeftSidedCell.self
    } else {
        return RightSidedCell.self
    }
}

无论如何,我不确定这是否可能,或者我对一个概念有一个基本的误解,但任何帮助都会非常感激。

谢谢。

ios swift types
3个回答
2
投票

首先,编写一个实现className()方法的协议(或者您将用于两个单元类的任何方法和属性)并使两个单元类符合它

protocol YourCellProtocol {
    var object : YourObjectClass? { get set }
    static func className() -> String
}

class LeftSidedCell : YourCellProtocol {...)
class RightSidedCell : YourCellProtocol {...}

然后你就可以做那样的事了

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let object = array.item(at: indexPath.row) else {
        fatalError("Could not retrieve the table object")
    }

    var type : YourCellProtocol.Type
    if object.displayOnLeft {
        type = LeftSidedCell.self
    } else {
        type = RightSidedCell.self
    }

    let cell = tableView.dequeueReusableCell(withIdentifier: type.className, for: indexPath)
    if let yourCell = cell as? YourCellProtocol
    {
        yourCell.object = object
    }

    return cell
}

2
投票

只要LeftSidedCell和RightSidedCell有一个共同的超类 - 比如MySidedCell - 你可以将它们存储在MySidedCell.Type类型的变量中:

let cellType : MySidedCell.Type = LeftSidedCell.self

您可以稍后使用==测试该值,以查看它是哪种单元格类型。

if cellType == LeftSidedCell.self {

1
投票

请记住,您正在使用如此多的可选检查和那些fataError调用来阻塞您的代码。当调用cellForRow时,您应该已经确定您的数据源是正确的。因此,此时无需选择性地展开您的数据和表格视图单元格,因为如果数据不正确,应用程序将会崩溃。

例如。在调用numberOfRowsInSection之前检查一下你的数组是否没有项目或项目是否无效,如果你的数据不正确则返回0项目和cellForRow将不会被错误的数据调用。

关于代码清洁,这对我有用:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let object = array[indexPath.row]
    let cell: UITableViewCell

    if object.displayOnLeft {
        cell = tableView.dequeueReusableCell(withIdentifier: "LeftSidedCellIdentifier", for: indexPath) as! LeftSidedCell
    } else {
        cell = tableView.dequeueReusableCell(withIdentifier: "RightSidedCellIdentifier", for: indexPath) as! RightSidedCell
    }

    cell.object = object
    return cell
}
© www.soinside.com 2019 - 2024. All rights reserved.