Ios Swift中nib的自定义UITableViewCell
我正在尝试从nib创建自定义表视图单元格。我指的是这篇文章。我面临两个问题 我创建了一个.xib文件,其中拖拽了一个UITableViewCell对象。我创建了一个子类Ios Swift中nib的自定义UITableViewCell,ios,uitableview,swift,ios8,Ios,Uitableview,Swift,Ios8,我正在尝试从nib创建自定义表视图单元格。我指的是这篇文章。我面临两个问题 我创建了一个.xib文件,其中拖拽了一个UITableViewCell对象。我创建了一个子类UITableViewCell,并将其设置为单元格的类,将其设置为可重用标识符 import UIKit class CustomOneCell: UITableViewCell { @IBOutlet weak var middleLabel: UILabel! @IBOutlet weak var left
UITableViewCell
,并将其设置为单元格的类,将其设置为可重用标识符
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:ForRowatineXpath:'具有不兼容的类型”(UITableView!、CustomOneCell!、NSIndexPath!)->()”
有人知道如何解决这些错误吗?这些似乎在Objective-C中工作得很好
多谢各位
编辑:我刚刚注意到,如果我将模拟器的方向更改为横向,并将其恢复为纵向,细胞就会出现!我还是不知道发生了什么。如果您有时间快速查看,我上传了一个Xcode项目来演示问题。对于Swift 5和iOS 12.2,您应该尝试以下代码来解决问题: 斯威夫特 TableViewController.swift
下图显示了一组约束,这些约束与提供的代码一起工作,而没有来自Xcode的任何约束模糊消息: 对于修复“重写方法…具有不兼容类型…”错误,我已将函数声明更改为
override func tableView(tableView: (UITableView!),
cellForRowAtIndexPath indexPath: (NSIndexPath!))
-> UITableViewCell {...}
(was
->UITableViewCell!
--末尾带有感叹号)以下是我使用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
...
要创建自定义单元格,再次将表视图单元格对象放入空的TableCellNib.xib文件中。这一次,在cell.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文件(表),以及如何注册nib以供单元使用
希望这有帮助 另一种可能适合您的方法(我就是这样做的)是注册一个类 假设您创建了自定义tableView,如下所示:
class UICustomTableViewCell: UITableViewCell {...}
然后,您可以使用“registerClass”将此单元格注册到要在其中显示它的任何UITableViewController中:
您可以在cell for row方法中调用它:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("UICustomTableViewCellIdentifier", forIndexPath: indexPath) as! UICustomTableViewCell
return cell
}
使用classUITableViewCell简单获取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
}
100%工作无任何问题(已测试)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
}
您没有按以下方式注册nib:
tableView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCell")
swift 4.1.2
xib
创建ImageCell2.swift
第一步
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)
}
}
第二步。根据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
}
}
带有屏幕截图的详细解决方案
MyCustomCell.xib
UITableViewCell
作为xib文件和任何其他所需可视组件的根MyCustomCell
作为UITableViewCell
的子类UIViewController
以使用自定义单元格我必须确保在创建出口时指定我是挂接到单元格,而不是对象的所有者。当菜单出现命名时,您必须在“对象”下拉菜单中选择它。当然,您也必须将单元格声明为类,而不仅仅是“TableViewCellClass”。否则,我将继续获取不符合密钥的类。此行加载项
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()
//启动电池
静态变量标识符:字符串{
返回字符串(描述:self)} 静态变量nib:UINib{ 返回UINib(nibName:identifier,bundle:nil)
}谢谢您的回复。但这也不起作用。是否需要更改表视图控制器中的任何内容?因为它仍然设置为原型单元格。继续使用原型单元格。但是,请确保您已经设置了良好的自动布局约束(如果您使用自动布局)。我上传了一个测试项目,演示了我遇到的问题。如果你有时间,你能看一下吗?你的测试项目证实了这一点:我在你的.xib文件中为你的自定义单元格设置了一些自动布局约束后,我能够使你的应用程序正常工作。看看你是否需要
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)
}
}
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
}
}
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
}
...
}
}
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()