ios - таблица - uitableviewdelegate swift 4




Пользовательский UITableViewCell от nib в Swift (4)

Я пытаюсь создать пользовательскую ячейку вида таблицы из наконечника. Я имею в виду эту статью here . Я столкнулся с двумя проблемами.

Я создал файл .xib с объектом UITableViewCell, который был перенесен на него. Я создал подкласс UITableViewCell и установил его как класс ячейки и Cell как идентификатор многократного использования.

import UIKit

class CustomOneCell: UITableViewCell {

    @IBOutlet weak var middleLabel: UILabel!
    @IBOutlet weak var leftLabel: UILabel!
    @IBOutlet weak var rightLabel: UILabel!

    required init(coder aDecoder: NSCoder!) {
        super.init(coder: aDecoder)
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

В UITableViewController у меня есть этот код,

import UIKit

class ViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate {

    var items = ["Item 1", "Item2", "Item3", "Item4"]

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    // MARK: - UITableViewDataSource
    override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }

    override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
        let identifier = "Cell"
        var cell: CustomOneCell! = tableView.dequeueReusableCellWithIdentifier(identifier) as? CustomOneCell
        if cell == nil {
            tableView.registerNib(UINib(nibName: "CustomCellOne", bundle: nil), forCellReuseIdentifier: identifier)
            cell = tableView.dequeueReusableCellWithIdentifier(identifier) as? CustomOneCell
        }

        return cell
    }
}

Этот код не соответствует ошибкам, но когда я запускаю его в симуляторе, он выглядит так.

В UITableViewController в раскадровке я ничего не сделал с ячейкой. Пустой идентификатор и отсутствие подкласса. Я попытался добавить идентификатор ячейки в ячейку прототипа и снова запустить его, но получаю тот же результат.

Еще одна ошибка, с которой я столкнулся, заключается в том, что я попытался реализовать следующий метод в UITableViewController.

override func tableView(tableView: UITableView!, willDisplayCell cell: CustomOneCell!, forRowAtIndexPath indexPath: NSIndexPath!) {

    cell.middleLabel.text = items[indexPath.row]
    cell.leftLabel.text = items[indexPath.row]
    cell.rightLabel.text = items[indexPath.row]
}

Как показано в статье, о которой я упоминал, я изменил форму типа cell UITableViewCell на CustomOneCell который является моим подклассом UITableViewCell. Но я получаю следующую ошибку,

Переопределяющий метод с селектором «tableView: willDisplayCell: forRowAtIndexPath:« имеет несовместимый тип »(UITableView !, CustomOneCell !, NSIndexPath!) -> () '

Кто-нибудь знает, как разрешить эти ошибки? Казалось, что они отлично работают в Objective-C.

Спасибо.

EDIT: Я только заметил, если я изменил ориентацию симулятора на пейзаж и вернул его к портрету, ящики появятся! Я все еще не мог понять, что происходит. Я загрузил проект Xcode, демонстрируя проблему, если у вас есть время для быстрого просмотра.


Swift 4

Регистрация Nib

tblMissions.register(UINib(nibName: "MissionCell", bundle: nil), forCellReuseIdentifier: "MissionCell")

В TableView DataSource

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
          guard let cell = tableView.dequeueReusableCell(withIdentifier: "MissionCell", for: indexPath) as? MissionCell else { return UITableViewCell() }
          return cell
    }

Вот мой подход с использованием Swift 2 и Xcode 7.3. В этом примере будет использоваться один ViewController для загрузки двух файлов .xib - один для UITableView и один для UITableCellView.

В этом примере вы можете удалить UITableView прямо в пустой файл .XIB TableNib. Внутри установите владельца файла в класс ViewController и используйте выход для ссылки на tableView.

а также

Теперь, в вашем контроллере вида, вы можете делегировать tableView, как обычно, так

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    ...

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        // Table view delegate
        self.tableView.delegate = self
        self.tableView.dataSource = self

        ...

Чтобы создать свою пользовательскую ячейку, снова удалите объект Cell View Table в пустой файл .Xib TableCellNib. На этот раз в файле .xib ячейки вам не нужно указывать «владелец», но вам нужно указать пользовательский класс и идентификатор типа «TableCellId»,

Создайте свой подкласс с любыми точками, которые вам нужны

class TableCell: UITableViewCell {

    @IBOutlet weak var nameLabel: UILabel!

}

Наконец ... обратно в ваш контроллер просмотра, вы можете загружать и отображать всю вещь, как это

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    // First load table nib
    let bundle = NSBundle(forClass: self.dynamicType)
    let tableNib = UINib(nibName: "TableNib", bundle: bundle)
    let tableNibView = tableNib.instantiateWithOwner(self, options: nil)[0] as! UIView

    // Then delegate the TableView
    self.tableView.delegate = self
    self.tableView.dataSource = self

    // Set resizable table bounds
    self.tableView.frame = self.view.bounds
    self.tableView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]

    // Register table cell class from nib
    let cellNib = UINib(nibName: "TableCellNib", bundle: bundle)
    self.tableView.registerNib(cellNib, forCellReuseIdentifier: self.tableCellId)

    // Display table with custom cells
    self.view.addSubview(tableNibView)

}

Код показывает, как вы можете просто загружать и отображать файл nib (таблица), а во-вторых, как регистрировать наконечник для использования ячейки.

Надеюсь это поможет!!!


Для исправления ошибки «Метод переопределения ... имеет несовместимый тип ...». Я изменил объявление функции на

override func tableView(tableView: (UITableView!), 
                        cellForRowAtIndexPath indexPath: (NSIndexPath!)) 
    -> UITableViewCell {...}

(был -> UITableViewCell! - с восклицательным знаком в конце)


Другой метод, который может работать для вас (как я это делаю), - это регистрация класса.

Предположим, что вы создаете пользовательский tableView следующим образом:

class UICustomTableViewCell: UITableViewCell {...}

Затем вы можете зарегистрировать эту ячейку в любом UITableViewController, который вы будете отображать с помощью «registerClass»:

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.registerClass(UICustomTableViewCell.self, forCellReuseIdentifier: "UICustomTableViewCellIdentifier")
}

И вы можете назвать это так, как вы ожидали бы в ячейке для метода row:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("UICustomTableViewCellIdentifier", forIndexPath: indexPath) as! UICustomTableViewCell
    return cell
}






ios8