我正在尝试从笔尖创建自定义表格视图单元格。我指的是这篇文章here。我面临两个问题。
我创建了一个带有 UITableViewCell 对象的 .xib 文件。我创建了一个 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
}
}
这段代码没有错误,但是当我在模拟器中运行它时,它看起来像这样。
https://i.stack.imgur.com/sElI3m.png
在情节提要的 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 中运行良好。
谢谢你。
编辑:我只是注意到如果我将模拟器的方向更改为横向并将其转回纵向,单元格就会出现!我仍然无法弄清楚发生了什么。如果您有时间快速浏览一下,我上传了一个 Xcode 项目 here 来演示该问题。
使用 Swift 5 和 iOS 12.2,您应该尝试以下代码来解决您的问题:
CustomCell.swift
import UIKit
class CustomCell: UITableViewCell {
// Link those IBOutlets with the UILabels in your .XIB file
@IBOutlet weak var middleLabel: UILabel!
@IBOutlet weak var leftLabel: UILabel!
@IBOutlet weak var rightLabel: UILabel!
}
TableViewController.swift
import UIKit
class TableViewController: UITableViewController {
let items = ["Item 1", "Item2", "Item3", "Item4"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCell")
}
// MARK: - UITableViewDataSource
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
cell.middleLabel.text = items[indexPath.row]
cell.leftLabel.text = items[indexPath.row]
cell.rightLabel.text = items[indexPath.row]
return cell
}
}
下图显示了一组与提供的代码一起工作的约束,没有来自 Xcode 的任何约束歧义消息:
https://i.stack.imgur.com/inEmw.png
这是我使用 Swift 2 和 Xcode 7.3 的方法。此示例将使用单个 ViewController 加载两个 .xib 文件——一个用于 UITableView,一个用于 UITableCellView。
https://i.stack.imgur.com/D3GY0.png
对于此示例,您可以将 UITableView 直接放入空的 TableNib.xib 文件中。在内部,将文件的所有者设置为您的 ViewController 类并使用插座来引用 tableView。
https://i.stack.imgur.com/ru1hA.png
和
https://i.stack.imgur.com/SXkze.png
现在,在您的视图控制器中,您可以像往常一样委托 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”
https://i.stack.imgur.com/EFvT3.png
使用您需要的任何插座创建您的子类
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 文件(表格),以及如何注册 nib 以供单元格使用。
希望这可以帮助!!!
let tableCellId = "myAwesomeCell"
。我添加了另一张图片来帮助你。
斯威夫特 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。
https://i.stack.imgur.com/rSOjZ.png
添加一个 UITableViewCell 作为您的 xib 文件的根目录以及您想要的任何其他可视组件。
https://i.stack.imgur.com/MyQ6n.png
创建一个类名为 MyCustomCell 的 cocoa touch 类文件作为 UITableViewCell 的子类。
https://i.stack.imgur.com/POlA9.png
为您的自定义表格视图单元设置自定义类和重用标识符。
https://i.stack.imgur.com/q5J6a.png
打开助手编辑器并 ctrl+drag 为您的视觉组件创建插座。
https://i.stack.imgur.com/L9Hyx.png
配置 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
在 Attribute Inspector
的 Table View Cell
中没有 identifier
。所以...发生了运行时错误。
.swift
和 tableView?.register(blahblah, forCellReuseIdentifier: "myCell")
中为标识符声明了相同的名称?我认为其中一个不是必需的,但是..我发现两者都是必不可少的。
.xib
可以包含多个 UITableViewCell
所以.. .xib
不足以.. 找到正确的单元格。
迅捷4.1.2
西布。
创建 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
}
}
您没有按如下方式注册您的笔尖:
tableView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCell")
另一种可能对您有用的方法(我就是这样做的)是注册一个类。
假设您创建了一个自定义 tableView,如下所示:
class UICustomTableViewCell: UITableViewCell {...}
然后,您可以使用“registerClass”在任何 UITableViewController 中注册此单元格:
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!
- 末尾有感叹号)
我必须确保在创建插座时指定我连接到单元格,而不是对象的所有者。当菜单出现命名时,您必须在“对象”下拉菜单中选择它。当然,您也必须将单元格声明为您的类,而不仅仅是“TableViewCellClass”。否则我会继续让课程不符合密钥要求。
简单地使用类 UITableViewCell 的 xib。根据要求设置 UI 并分配 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
}
https://i.stack.imgur.com/p0vfF.png
100% 正常工作(已测试)
此行在 TableView
单元格中添加:
static var nib : UINib{
return UINib(nibName: identifier, bundle: nil)
}
static var identifier : String{
return String(describing: self)
}
并在视图控制器中注册,如
此行在 viewDidLoad
中使用
tableview.register(TopDealLikedTableViewCell.nib, forCellReuseIdentifier: TopDealLikedTableViewCell.identifier)
索引路径处的行单元格
if let cell = tableView.dequeueReusableCell(withIdentifier:
TopDealLikedTableViewCell.identifier) as? TopDealLikedTableViewCell{
return cell
}
return UITableViewCell()
设置在单元格上
static var identifier : String {
return String(describing: self)
}
static var nib : UINib {
return UINib(nibName: identifier, bundle: nil)
}