Использование атрибута @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
, чтобы назвать наши подклассы HeaderCell
, ContentsCell
и 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
}