Эффективный способ выбрать тип пользовательского UITableViewCell для возврата - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть UITableViewController, который отображает количество строк, содержащих пользовательские типы UITableViewCell

Ячейки разделены на 2 категории, а затем еще 3 подкатегории.

система> текст / мультимедиа / интерактив

пользователь> текст / мультимедиа / интерактивный

В настоящее время я использую переключатель с вложенным переключателем для назначения правильного типа ячейки.

Это, однако, выглядит не очень хорошо.Не думаю, что это лучший способ добиться этого, но я не уверен, как еще подойти к этому.

Я не использую раскадровки.

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) ")
        }
    }
}

1 Ответ

0 голосов
/ 13 декабря 2018

Вы можете закодировать поиск класса в словарь, который значительно уменьшит код:

// 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
             ]
]

Тогда код для получения ячейки станет:

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) ")
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...