Использование атрибута @objc

План

  • Создание приложения для простого просмотра таблиц
  • Загрузите таможенные ячейки в каждую строку
  • Идентификатор ячейки – это имя класса, если объект – TableCell, идентификатор ячейки – «TableCell»
  • Используйте общие методы загрузки клеток
  • Используйте вспомогательный метод для загрузки ячейки с помощью атрибута @objc

Создание подкласса UITableViewCell

class HeaderCell: UITableViewCell {
    ...
}
class ContentsCell: UITableViewCell {
    ...
}
class AboutCell: UITableViewCell {
    ...
}

Ячейка загрузки в Tableview, созданная традиционным способом

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.row == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "HeaderCell", for: indexPath) as? HeaderCell
        return cell
    }
    if indexPath.row == 2 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "ContentsCell", for: indexPath) as? ContentsCell
        return cell
    }
    if indexPath.row == 1 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "AboutCell", for: indexPath) as? AboutCell
        return cell
    }
    return UITableViewCell()
}

Так что же такое атрибут @objc ?
Когда вы применяете его к классу или методу, он инструктирует Swift сделать эти вещи доступными для Objective-C, а также для кода Swift.

В большинстве случаев, когда вы вызываете метод из UIBarButtonItem или UIButton, вам нужно пометить этот метод с помощью @objc, чтобы он был открыт – они и многие другие являются кодом Objective-C.

В этом случае мы будем использовать @objc, чтобы назвать наши подклассы HeaderCellContentsCell и AboutCell в Swift

Обновите наш подкласс UITableViewCell

@objc(HeaderCell)
class HeaderCell: UITableViewCell {
    ...
}
@objc(ContentsCell)
class ContentsCell: UITableViewCell {
    ...
}
@objc(AboutCell)
class AboutCell: UITableViewCell {
    ...
}

Создайте вспомогательный метод для получения идентификатора ячейки, используя тип AnyClass из подкласса UITableViewCell.

Примечание. Идентификатором ячейки должно быть имя класса.

func getCell(_ cls: AnyClass, _ index: IndexPath) -> AnyObject {
    let identifier = NSStringFromClass(cls)
    let cell = tableView.dequeueReusableCell(withIdentifier: identifier, for: index)
    return cell
}

Ячейка загрузки в Tableview по новому способу

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.row == 0 {
        let cell = getCell(HeaderCell.self, indexPath) as! HeaderCell
        return cell
    }
    if indexPath.row == 2 {
        let cell = getCell(ContentsCell.self, indexPath) as! ContentsCell
        return cell
    }
    if indexPath.row == 1 {
        let cell = getCell(AboutCell.self, indexPath) as! AboutCell
        return cell
    }
    return UITableViewCell()
}

@objc атрибут предназначен не только для методов, он так же используется для наименования класса.

Дополнительные хитрости

Так же можно сделать код короче, создав перечисление строк под названием Row

enum Row: Int {
    case HeaderCell = 0
    case ContentsCell = 1
    case AboutCell  = 2
    
    var className: AnyClass {
        switch self {
            case .Header:
                return HeaderCell.self
            case .Contents:
                return ContentsCell.self
            case .About:
                return AboutCell.self
        }
    }
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let row = Row(rawValue: indexPath.row)
    let cell = getCell(row.className, indexPath) // dynamic binding
    return cell
}

Ответить