Swift中的自定义UITableViewCell寄存器类

Swift中的自定义UITableViewCell寄存器类,uitableview,swift,ios8,Uitableview,Swift,Ios8,在我的应用程序中,我根据数组填充表。该表使用自定义UITableViewCell。一切都很好,桌子已经满了。然后我将搜索显示控制器添加到我的UITableViewController中,无需编写代码来处理搜索,只需添加控制器即可。运行应用程序时,该表仍被填充。但如果我尝试单击搜索栏,则会出现错误: 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无法将标识符为CitiesListCell的单元格出列-必须为标识符注册nib或类,或在情节

在我的应用程序中,我根据数组填充表。该表使用自定义UITableViewCell。一切都很好,桌子已经满了。然后我将搜索显示控制器添加到我的UITableViewController中,无需编写代码来处理搜索,只需添加控制器即可。运行应用程序时,该表仍被填充。但如果我尝试单击搜索栏,则会出现错误:

由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无法将标识符为CitiesListCell的单元格出列-必须为标识符注册nib或类,或在情节提要中连接原型单元格”

我尝试在UITableViewController行中添加viewDidLoad函数:

self.tableView.registerClass(MyCell.classForCoder(),forCellReuseIdentifier:kCelliIdentifier)

启动应用程序并立即获取错误信息:

致命错误:在展开可选值时意外发现nil

第行
cell.cellMyCity.text=cellText

我做错了什么

这是我的自定义UITableViewCell类:

import UIKit

class MyCell: UITableViewCell {

@IBOutlet var cellMyImage: UIImageView
@IBOutlet var cellMyCity: UILabel
@IBOutlet var cellMyCountry: UILabel
@IBOutlet var cellMyTemp: UILabel

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

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

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

}
}
这是单元格的代码:

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

    var cell = tableView.dequeueReusableCellWithIdentifier(kCellIdentifier, forIndexPath: indexPath) as MyCell!

    if cell == nil {
        cell = MyCell(style: UITableViewCellStyle.Default, reuseIdentifier: kCellIdentifier)
    }

    let cellText: String? = dataWeatherSelectedCity[indexPath.row].name as  String
    println("Строка: \(cellText)")
    cell.cellMyCity.text = cellText

    let cellSubtitle: String? = dataWeatherSelectedCity[indexPath.row].country as String
    cell.cellMyCountry.text = cellSubtitle

    cell.cellMyImage.image = UIImage(named: "Blank52")

    var currentCityWeatherURL = "http://api.wunderground.com/api/\(self.myAPI.kWundergroundApiKey)/conditions/lang:RU/q/zmw:\(self.dataWeatherSelectedCity[indexPath.row].zmv).json"

    var fullObservation:NSDictionary = self.myAPI.jsonParsingWeather(currentCityWeatherURL)
    var currentObservation:NSDictionary = fullObservation.valueForKey("current_observation") as NSDictionary

    var currentWeather = self.myAPI.parsingOneCityCurrentCondition(currentObservation)       
    cell.cellMyImage.image = currentWeather.image
    cell.cellMyTemp.text = currentWeather.temp
    return cell
}
TableViewCell中的属性:

没有
self.tableView.registerClass(MyCell.classForCoder(),forCellReuseIdentifier:kCelliIdentifier)的表
self.tableView.registerClass(MyCell.self,forCellReuseIdentifier:kCelliIdentifier)


错误提示您正在获取
单元格或
UITestField
nil
Swift
不支持对nil对象的方法调用,这就是为什么会发生崩溃。通过检查对象是否为零,可以防止崩溃

if var label = cell.cellMyCity{
    label.text = cellText
}
    override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {

    var cell = tableView.dequeueReusableCellWithIdentifier(kCellIdentifier) as MyCell!
    if cell == nil {
        //tableView.registerNib(UINib(nibName: "UICustomTableViewCell", bundle: nil), forCellReuseIdentifier: "UICustomTableViewCell")
        tableView.registerClass(MyCell.classForCoder(), forCellReuseIdentifier: kCellIdentifier)

        cell = MyCell(style: UITableViewCellStyle.Default, reuseIdentifier: kCellIdentifier)
    }
    if var label = cell.cellMyCity{
        label.text = countryList[indexPath.row]
    }
    else{
        cell.textLabel.text = countryList[indexPath.row]
    }
    return cell
}
编辑

我想我明白了这里的问题是什么

在<代码>情节提要<代码>中有拖放<代码>UISearchBar
,因此默认情况下,所有数据源和委托都设置为控制器,例如,
视图控制器
(覆盖UITableView数据源方法的类),并在该
视图控制器
中注册MyCell类作为自定义类。 因此,您的tableView显示得非常完美,但当您在UISearchBar中键入内容时,会调用相同的数据源方法(
ViewController
),并在那里为
searchResultsTableView
UISearchDisplayController
显示搜索结果的tableView)注册MyCell,但这并不了解MyCell,这就是为什么在搜索中,
cell.cellMyCity
为零,这意味着
searchResultsTableView
除了默认的
UITableViewCell
之外,您没有为默认单元格设置任何内容,例如-

cell.textLabel.text = countryList[indexPath.row]
您可以通过如下更改数据源方法来观察整个场景

if var label = cell.cellMyCity{
    label.text = cellText
}
    override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {

    var cell = tableView.dequeueReusableCellWithIdentifier(kCellIdentifier) as MyCell!
    if cell == nil {
        //tableView.registerNib(UINib(nibName: "UICustomTableViewCell", bundle: nil), forCellReuseIdentifier: "UICustomTableViewCell")
        tableView.registerClass(MyCell.classForCoder(), forCellReuseIdentifier: kCellIdentifier)

        cell = MyCell(style: UITableViewCellStyle.Default, reuseIdentifier: kCellIdentifier)
    }
    if var label = cell.cellMyCity{
        label.text = countryList[indexPath.row]
    }
    else{
        cell.textLabel.text = countryList[indexPath.row]
    }
    return cell
}
就解决方案而言,有两种可能的解决方案

A) 。不要使用
searchResultsTableView
(由
UISearchDisplayController
提供)并在与
ViewController
相同的
tableView
中显示搜索结果。为此,您可以做的是-当用户在
UISearchBar
中键入某些内容时,聆听
UISearchBar
委托,通过谓词获取结果数据源(可能在不同的数组中),并在相同的
UITableView
中显示结果


B) 。自定义UISearchDisplayController并在
searchResultsTableView

中使用自定义单元格(即MyCell),我所做的工作如下:

class MainViewController: UIViewController {

    // ...

    @IBOutlet var tableView: UITableView

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.registerNib(UINib(nibName: "UICustomTableViewCell", bundle: nil), forCellReuseIdentifier: "UICustomTableViewCell")

        // ...
    }

    // ...

}
注意:如果我使用
–registerClass(\uu:forCellReuseIdentifier:)
方法,则不会加载xib文件,因此,除非以编程方式将内容添加到单元格中,否则不会显示实际的自定义界面。如果要从nib文件加载接口,则需要使用其nib注册该单元


符合基本协议:

extension MainViewController: UITableViewDataSource {
    
    func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
        return 3
    }
    
    func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
        let cell: UICustomTableViewCell = tableView.dequeueReusableCellWithIdentifier(UICustomTableViewCell.reuseIdentifier) as UICustomTableViewCell
        println(cell)
        return cell;
    }
    
}

//

extension MainViewController: UITableViewDelegate {
    
    func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
        return 44.0
    }
    
}

自定义单元格类是一个非常通用的类,有一个有意义的名称,如
UICustomTableViewCell

class UICustomTableViewCell: UITableViewCell {

    class var reuseIdentifier: String {
        get {
            return "UICustomTableViewCell"
        }
    }
    
    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
    }
    
}

具有非常随机的界面:

自定义类和重用标识符的这些设置:


屏幕上的最终结果与我预期的一样,有3行:

注意:为了进一步自定义自定义单元格,您可能需要扩展上述代码

更新 使用
UISearchBar
,最终结果如下:

class MainViewController: UIViewController {

    // ...

    @IBOutlet var tableView: UITableView

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.registerNib(UINib(nibName: "UICustomTableViewCell", bundle: nil), forCellReuseIdentifier: "UICustomTableViewCell")

        // ...
    }

    // ...

}

tableView
之前添加
self
修复了以下问题:

var cell = self.tableView.dequeueReusableCellWithIdentifier(kCellIdentifier, forIndexPath: indexPath) as MyCell!

您必须记住为使用该单元格的任何tableView注册该单元格,包括searchDisplayController.tableView。

如果您使用的是storyboard,请确保删除register类,因为它将覆盖storyboard以及与之关联的所有大纲链接

请查收


它对我有效=)

我在你的帖子中没有看到你在IB中为你的手机设置了重用标识符……更新的图片在哪里?我没有看到任何…现在你看到我编辑的帖子中的图片了吗?你试过
object\u getClass(MyCell)
而不是
MyCell.classForCoder()
MyCell.self
?在Swift中,这在逻辑上看起来更为正确…刚刚尝试过-
由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因是:“必须传递一个UITableViewCell类”
你每次都得到cell对象零吗?如果我使用
self.tableView.registerClass(MyCell.self,forCellReuseIdentifier:kCelliIdentifier)
-然后每次。如果我不使用这个,那么所有的好表填充。但粉碎搜索显示控制器感谢有用的答案!我还是不明白这个问题!但这个问题解决了,我的意思是,我确实需要为一个细胞制造xib?如果没有它,它将无法工作?不,您不需要为自定义单元格创建xib,您可以通过编程方式创建自定义内容整体,如果您更喜欢这种方式。您能建议如何创建