首页 文章

从Swift中的nib定制UITableViewCell

提问于
浏览
108

我'm trying to create a custom table view cell from a nib. I' m指的是这篇文章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
    }
}

这段代码没有错误,但是当我在模拟器中运行它时,它看起来像这样 .

enter image description here

在故事板中的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的子类 . 但我得到以下错误,

Overriding method with selector 'tableView:willDisplayCell:forRowAtIndexPath:' has incompatible type '(UITableView!, CustomOneCell!, NSIndexPath!) -> ()'

任何人都知道如何解决这些错误?这些似乎在Objective-C中工作正常 .

谢谢 .

编辑:我只是注意到,如果我改变模拟器's orientation to landscape and turn it back to portrait, the cells appear! I still couldn'吨弄清楚发生了什么 . 如果您有时间快速查看,我上传了一个Xcode项目here来演示问题 .

8 回答

  • 167

    您应该为您的项目尝试以下代码:( Swift 3的语法)

    CustomOneCell.swift

    import UIKit
    
    class CustomOneCell: 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: "CustomOneCell", bundle: nil), forCellReuseIdentifier: "CustomCellOne")    
        }
    
        // MARK: - UITableViewDataSource
    
        override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return items.count
        }
    
        override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCellWithIdentifier("CustomCellOne", forIndexPath: indexPath) as! CustomOneCell
    
            cell.middleLabel.text = items[indexPath.row]
            cell.leftLabel.text = items[indexPath.row]
            cell.rightLabel.text = items[indexPath.row]
    
            return cell
        }
    }
    

    下图显示了一组约束,这些约束与提供的代码一起使用,而没有来自Xcode的任何约束歧义消息 .

    enter image description here

  • 26

    这是我使用Swift 2和Xcode 7.3的方法 . 此示例将使用单个ViewController加载两个.xib文件 - 一个用于UITableView,另一个用于UITableCellView .

    enter image description here

    对于此示例,您可以将UITableView权限放入空的 TableNib .xib文件中 . 在里面,将 file's owner 设置为ViewController类,并使用插座引用tableView .

    enter image description here

    enter image description here

    现在,在视图控制器中,您可以像往常一样委托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文件中 . 这次,在单元.xib文件中,您不必指定"owner",但是您需要指定 Custom Classidentifier ,如"TableCellId"

    enter image description here

    enter image description here

    使用您需要的任何插件创建子类,如此

    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)
    
    }
    

    代码显示了如何简单地加载和显示nib文件(表),以及如何注册nib以供单元使用 .

    希望这可以帮助!!!

  • 2

    斯威夫特4

    注册笔尖

    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
        }
    
  • 0

    为了修复"Overriding method... has incompatible type..."错误,我已将函数声明更改为

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

    (是 -> UITableViewCell! - 末尾带有感叹号)

  • -1

    另一种可能对你有用的方法(就是我这样做的方法)是注册一个类 .

    假设您创建一个自定义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
    }
    
  • 0

    简单地使用类 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
    }
    

    enter image description here

    100% working without any issue (Tested)

  • 2

    你没有注册你的笔尖如下:

    tableView.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "CustomCell")
    
  • 6

    [![在此处输入图片说明] [1]] [1]

    迅捷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)
        }
    
    }
    step 2 . According Viewcontroller class
    

    导入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 {
    

    [在此输入图像描述] [2]让cell = tableView.dequeueReusableCell(withIdentifier:“ImageCell2”)为! 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:“) “),占位符:UIImage.init(名称:”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}

    }

相关问题