在我的应用程序中,我在数组的基础上填写表格。该表使用自定义UITableViewCell。一切正常,桌子就满了。然后我将搜索显示控制器添加到我的UITableViewController,没有写代码来处理搜索,只需添加控制器。当您运行该应用程序时,该表仍然填充。但如果我尝试单击搜索栏,则会收到错误:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier CitiesListCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
我尝试在UITableViewController行中添加我的viewDidLoad函数:
self.tableView.registerClass(MyCell.classForCoder(), forCellReuseIdentifier: kCellIdentifier)
启动应用程序并立即收到错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
排队cell.cellMyCity.text = cellText
我做错了什么?
这是我的Custom 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: kCellIdentifier)
或self.tableView.registerClass(MyCell.self, forCellReuseIdentifier: kCellIdentifier)
的表:
答案 0 :(得分:18)
我做的工作是这样的:
class MainViewController: UIViewController {
// ...
@IBOutlet var tableView: UITableView
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerNib(UINib(nibName: "UICustomTableViewCell", bundle: nil), forCellReuseIdentifier: "UICustomTableViewCell")
// ...
}
// ...
}
注意:如果我使用 –registerClass(_: forCellReuseIdentifier:)
方法,则不会加载xib文件,因此除非以编程方式添加内容,否则不会显示实际的自定义界面细胞。如果你想从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
,最终结果如下:
答案 1 :(得分:10)
在self
之前添加tableView
解决问题:
var cell = self.tableView.dequeueReusableCellWithIdentifier(kCellIdentifier, forIndexPath: indexPath) as MyCell!
答案 2 :(得分:8)
由于错误提示您的cell
或UITestField
nil
和Swift
不支持对nil对象的方法调用,这就是为什么你正在崩溃。你可以通过检查对象是否为nil来防止崩溃
if var label = cell.cellMyCity{
label.text = cellText
}
修改强>
我想我在这里遇到了什么问题......
您已在UISearchBar
中拖放storyboard
,因此默认设置为控制器的所有数据源和委托代表ViewController
(在其中覆盖UITableView DataSource方法的类)并在ViewController
中注册MyCell类作为自定义类。
所以你的tableView显示完美但是当你输入UISearchBar的东西时,同样调用了相同的DataSource方法(ViewController
),你为searchResultsTableView
注册MyCell(UISearchDisplayController
tableView显示搜索结果) ,但这并不了解MyCell以及为什么cell.cellMyCity
在搜索时为零的原因,这意味着searchResultsTableView
期望默认UITableViewCell
而你是不为默认单元格设置任何内容,如 -
cell.textLabel.text = countryList[indexPath.row]
您可以通过将DataSource方法更改为
来观察整个场景 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
提供),并将您的搜索结果显示在与tableView
相同的ViewController
中。为此你可以做的是 - 当用户在UISearchBar
中键入一些东西时,听取UISearchBar
个委托,通过谓词和显示结果得到你的结果数据源(可能在不同的数组中){{1 }}
B)。自定义UISearchDisplayController并在UITableView
答案 3 :(得分:2)
答案 4 :(得分:1)
您必须记住为任何使用它的tableView注册单元格 - 包括searchDisplayController.tableView。