swift - 选择要返回的自定义 UITableViewCell 类型的有效方法

标签 swift uitableview

我有一个 UITableViewController,它呈现出许多行,其中包含自定义类型的 UITableViewCell

细胞分为 2 个类别,然后再分为 3 个子类别。

system > text / media / interactive

user > text / media / interactive

我目前使用带有嵌套开关的开关来分配正确的单元格类型。

然而,这看起来或感觉起来不是很好。我认为这不是实现此目标的最佳方法,但我不确定还有什么其他方法可以解决此问题。

我没有使用 Storyboard。

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let item = viewModel.history[indexPath.row]

    switch item.origin {
    case .system:
        switch item.type {
        case .text:
            let cell = tableView.dequeueReusableCell(withClass: BotMessageCell.self)
            cell.setContent(as: item)
            cell.layoutSubviews()
            return cell
        case .media:
            let cell = tableView.dequeueReusableCell(withClass: BotMediaCell.self)
            cell.setContent(as: item)
            cell.layoutSubviews()
            return cell
        case .interactive
            let cell = tableView.dequeueReusableCell(withClass: BotInteractiveCell.self)
            cell.setContent(as: item)
            cell.layoutSubviews()
            return cell
        default:
            fatalError("No dequeueReusableCell availble for cell of type \(item.type) ")
        }
    case .user:
        switch item.type {
        case .text:
            let cell = tableView.dequeueReusableCell(withClass: UserMessageCell.self)
            cell.setContent(as: item)
            cell.layoutSubviews()
            return cell
        case .media:
            let cell = tableView.dequeueReusableCell(withClass: UserMediaCell.self)
            cell.setContent(as: item)
            cell.layoutSubviews()
            return cell
        case .interactive
            let cell = tableView.dequeueReusableCell(withClass: UserInteractiveCell.self)
            cell.setContent(as: item)
            cell.layoutSubviews()
            return cell
        default:
            fatalError("No dequeueReusableCell availble for cell of type \(item.type) ")
        }
    }
}

最佳答案

您可以将类查找编码到字典中,这将大大减少代码:

// Protocol which all cells will adopt
protocol CustomCell {
    func setContent(as: Item)
}

// Here are the six classes which each must implement setContent()
class BotMessageCell: UITableViewCell, CustomCell { }
class BotMediaCell: UITableViewCell, CustomCell { }
class BotInteractiveCell: UITableViewCell, CustomCell { }
class UserMessageCell: UITableViewCell, CustomCell { }
class UserMediaCell: UITableViewCell, CustomCell { }
class UserInteractiveCell: UITableViewCell, CustomCell { }

// Enums for origin and item type    
enum Origin {
    case system
    case user
}

enum ItemType {
    case text
    case media
    case interactive
    case unknown
}

// Dictionary for looking up the class    
let dict: [Origin: [ItemType: AnyClass]] = [
    .system: [ .text:        BotMessageCell.self,
               .media:       BotMediaCell.self,
               .interactive: BotInteractiveCell.self
             ],
    .user:   [ .text:        UserMessageCell.self,
               .media:       UserMediaCell.self,
               .interactive: UserInteractiveCell.self
             ]
]

那么获取cell的代码就变成了:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let item = viewModel.history[indexPath.row]

    if let cellClass = dict[item.origin]?[item.type] {
        let cell = tableView.dequeueReusableCell(withClass: cellClass)
        (cell as? CustomCell)?.setContent(as: item)
        return cell
    }
    fatalError("No dequeueReusableCell availble for cell of type \(item.type) ")
}

关于swift - 选择要返回的自定义 UITableViewCell 类型的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53752202/

相关文章:

swift - 我可以从一个地方全局管理选项卡栏(而不是 Controller )吗?

ios - 根据indexPath Swift在TableView中设置UiCell文本颜色

ios - UITableView - 仅在触摸时突出显示单个单元格

swift - 将 podspec 添加到主干但该站点未正确显示我的 pod

ios - 在 Xcode UI 测试期间检查电子邮件?

ios - 底部 2 行未在我的 tableview 中注册触摸

ios - 在 UITableViewHeaderFooterView 中更改字体大小的问题

ios - 自定义UITableViewCell的索引路径

iphone - 在基于导航的应用程序中加载 UITableView 时出现问题

swift - 无法返回具有默认参数值的函数