Я пытаюсь создать настраиваемую ячейку представления таблицы из пера. Я имею в виду эту статью здесь . У меня две проблемы.
Я создал файл .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 в раскадровке я ничего не сделал с ячейкой. Пустой идентификатор и без подкласса. Я попытался добавить идентификатор Cell в ячейку прототипа и снова запустил его, но получил тот же результат.
Еще одна ошибка, с которой я столкнулся, - это когда я пытался реализовать следующий метод в 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.
Спасибо.
РЕДАКТИРОВАТЬ: Я только что заметил, что если я изменю ориентацию симулятора на альбомную и верну ее обратно в портретную, появятся ячейки! Я все еще не мог понять, что происходит. Я загрузил здесь проект Xcode, демонстрирующий проблему, если у вас есть время быстро взглянуть.
источник
Вот мой подход с использованием Swift 2 и Xcode 7.3. В этом примере будет использоваться один ViewController для загрузки двух файлов .xib - одного для UITableView и одного для UITableCellView.
В этом примере вы можете поместить UITableView прямо в пустой файл TableNib .xib. Внутри установите владельцем файла свой класс 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 ...
Чтобы создать пользовательскую ячейку, снова перетащите объект Table View Cell в пустой файл TableCellNib .xib. На этот раз в файле .xib ячейки вам не нужно указывать «владельца», но вам нужно указать настраиваемый класс и идентификатор, например «TableCellId».
Создайте свой подкласс с любыми выходами, которые вам нужны.
class TableCell: UITableViewCell { @IBOutlet weak var nameLabel: UILabel! }
Наконец ... вернувшись в свой View Controller, вы можете загрузить и отобразить все это так:
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) }
В коде показано, как можно просто загрузить и отобразить файл пера (таблицу), а во-вторых, как зарегистрировать перо для использования в ячейке.
Надеюсь это поможет!!!
источник
let tableCellId = "myAwesomeCell"
. Я добавил еще одно изображение, чтобы помочь вам.Swift 4
Зарегистрировать перо
override func viewDidLoad() { super.viewDidLoad() tblMissions.register(UINib(nibName: "MissionCell", bundle: nil), forCellReuseIdentifier: "MissionCell") }
В источнике данных TableView
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let cell = tableView.dequeueReusableCell(withIdentifier: "MissionCell", for: indexPath) as? MissionCell else { return UITableViewCell() } return cell }
источник
Подробное решение со скриншотами
MyCustomCell.xib
.UITableViewCell
качестве корня вашего файла xib и любых других визуальных компонентов, которые вы хотите.MyCustomCell
в качестве подклассаUITableViewCell
.ctrl+drag
создайте выходы для ваших визуальных компонентов.UIViewController
для использования пользовательской ячейки.class MyViewController: UIViewController { @IBOutlet weak var myTable: UITableView! override func viewDidLoad { super.viewDidLoad() let nib = UINib(nibName: "MyCustomCell", bundle: nil) myTable.register(nib, forCellReuseIdentifier: "MyCustomCell") myTable.dataSource = self } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if let cell = tableView.dequeueReusableCell(withIdentifier: "MyCustomCell") as? MyCustomCell { cell.myLabel.text = "Hello world." return cell } ... } }
источник
MyHeaderView.swift
для нестандартной ячейки..swift
Для заголовка вид не имеетidentifier
вTable View Cell
вAttribute Inspector
. итак ... произошла ошибка времени выполнения..swift
и intableView?.register(blahblah, forCellReuseIdentifier: "myCell")
? Я думал, что в одном из них нет необходимости, но .. Я обнаружил, что оба необходимы..xib
для пользовательской ячейки может быть несколько,UITableViewCell
поэтому ...xib
недостаточно, чтобы .. найти правильную ячейку.Вы не зарегистрировали перо, как показано ниже:
tableView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCell")
источник
Другой способ, который может сработать для вас (как я это делаю), - это регистрация класса.
Предположим, вы создаете настраиваемый tableView, как показано ниже:
class UICustomTableViewCell: UITableViewCell {...}
Затем вы можете зарегистрировать эту ячейку в любом UITableViewController, в котором вы будете отображать ее, с помощью "registerClass":
override func viewDidLoad() { super.viewDidLoad() tableView.registerClass(UICustomTableViewCell.self, forCellReuseIdentifier: "UICustomTableViewCellIdentifier") }
И вы можете вызвать его, как и следовало ожидать в ячейке для метода строки:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("UICustomTableViewCellIdentifier", forIndexPath: indexPath) as! UICustomTableViewCell return cell }
источник
Чтобы исправить ошибку «Метод переопределения ... имеет несовместимый тип ...», я изменил объявление функции на
override func tableView(tableView: (UITableView!), cellForRowAtIndexPath indexPath: (NSIndexPath!)) -> UITableViewCell {...}
(было
-> UITableViewCell!
- с восклицательным знаком в конце)источник
быстрый 4.1.2
xib.
Создать ImageCell2.swift
Шаг 1
import UIKit class ImageCell2: UITableViewCell { @IBOutlet weak var imgBookLogo: UIImageView! @IBOutlet weak var lblTitle: UILabel! @IBOutlet weak var lblPublisher: UILabel! override func awakeFromNib() { super.awakeFromNib() // Initialization code } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) } }
шаг 2 . Согласно классу Viewcontroller
import UIKit class ImageListVC: UIViewController,UITableViewDataSource,UITableViewDelegate { @IBOutlet weak var tblMainVC: UITableView! var arrBook : [BookItem] = [BookItem]() override func viewDidLoad() { super.viewDidLoad() //Regester Cell self.tblMainVC.register(UINib.init(nibName: "ImageCell2", bundle: nil), forCellReuseIdentifier: "ImageCell2") // Response Call adn Disply Record APIManagerData._APIManagerInstance.getAPIBook { (itemInstance) in self.arrBook = itemInstance.arrItem! self.tblMainVC.reloadData() } } //MARK: DataSource & delegate func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.arrBook.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // [enter image description here][2] let cell = tableView.dequeueReusableCell(withIdentifier: "ImageCell2") as! ImageCell2 cell.lblTitle.text = self.arrBook[indexPath.row].title cell.lblPublisher.text = self.arrBook[indexPath.row].publisher if let authors = self.arrBook[indexPath.row].author { for item in authors{ print(" item \(item)") } } let url = self.arrBook[indexPath.row].imageURL if url == nil { cell.imgBookLogo.kf.setImage(with: URL.init(string: ""), placeholder: UIImage.init(named: "download.jpeg")) } else{ cell.imgBookLogo.kf.setImage(with: URL(string: url!)!, placeholder: UIImage.init(named: "download.jpeg")) } return cell } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 90 } }
источник
Я должен был убедиться, что при создании розетки указывать, что я подключаюсь к ячейке, а не к владельцу объекта. Когда появится меню, чтобы назвать его, вы должны выбрать его в раскрывающемся меню «объект». Конечно, вы также должны объявить ячейку своим классом, а не просто TableViewCellClass. В противном случае я бы продолжал получать класс, не соответствующий ключу.
источник
Просто возьмите xib с классом UITableViewCell . Установите пользовательский интерфейс в соответствии с требованиями и назначьте IBOutlet. Используйте его в cellForRowAt () табличного представления следующим образом:
//MARK: - table method func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.arrayFruit.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { var cell:simpleTableViewCell? = tableView.dequeueReusableCell(withIdentifier:"simpleTableViewCell") as? simpleTableViewCell if cell == nil{ tableView.register(UINib.init(nibName: "simpleTableViewCell", bundle: nil), forCellReuseIdentifier: "simpleTableViewCell") let arrNib:Array = Bundle.main.loadNibNamed("simpleTableViewCell",owner: self, options: nil)! cell = arrNib.first as? simpleTableViewCell } cell?.labelName.text = self.arrayFruit[indexPath.row] cell?.imageViewFruit.image = UIImage (named: "fruit_img") return cell! } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 100.0 }
100% работает без каких-либо проблем (проверено)
источник
Эту строку добавьте в
TableView
ячейку:static var nib : UINib{ return UINib(nibName: identifier, bundle: nil) } static var identifier : String{ return String(describing: self) } And register in viewcontroller like //This line use in viewdid load tableview.register(TopDealLikedTableViewCell.nib, forCellReuseIdentifier: TopDealLikedTableViewCell.identifier) // cell for row at indexpath if let cell = tableView.dequeueReusableCell(withIdentifier: TopDealLikedTableViewCell.identifier) as? TopDealLikedTableViewCell{ return cell } return UITableViewCell()
источник