私のアプリケーションでは、配列に基づいてテーブルを埋めます。テーブルはカスタム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
_
私は何を間違えていますか?
これは私のカスタム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)
なしのテーブル:
エラーとして、cell
またはUITestField
nil
を取得していることを示唆しており、Swift
はnilオブジェクトのメソッド呼び出しをサポートしていないため、クラッシュします。オブジェクトがnilであるかどうかを確認することでクラッシュを防ぐことができます
if var label = cell.cellMyCity{
label.text = cellText
}
[〜#〜] edit [〜#〜]
ここで何が問題なのかわかったと思う...
UISearchBar
にドラッグアンドドロップstoryboard
があるため、デフォルトではすべてのデータソースとデリゲートがコントローラーに設定され、たとえばViewController
( UITableView DataSourceメソッドをオーバーライドするクラス)およびそのViewController
でMyCellクラスをカスタマイズクラスとして登録します。したがって、tableViewは完璧に表示されますが、UISearchBarに何かを入力すると、同じDataSourceメソッド(ViewController
)が呼び出され、そこにもMyCellをsearchResultsTableView
(UISearchDisplayController
tableView thatsに登録します検索結果)、しかし、それはMyCellを知らないので、cell.cellMyCity
は検索の場合はnilになります。つまり、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
}
解決策が懸念されるに関する限り、2つの解決策が考えられます。
A)。 searchResultsTableView
(UISearchDisplayController
で提供)を使用して、tableView
と同じViewController
に検索結果を表示しないでください。そのためにできることは、ユーザーがUISearchBar
に何かを入力したときにUISearchBar
デリゲートをリッスンし、Predicatesで結果データソースを取得し(同じ配列で結果を表示)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(_: 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
を使用すると、最終結果は次のようになります。
self
の前にtableView
を追加すると、問題が修正されます。
var cell = self.tableView.dequeueReusableCellWithIdentifier(kCellIdentifier, forIndexPath: indexPath) as MyCell!
ストーリーボードを使用している場合は、ストーリーボードとそれに関連付けられているすべてのアウトリンクを上書きするため、必ず登録クラスを削除してください
確認してください https://stackoverflow.com/a/26350795/445358
私のために働く=)
SearchDisplayController.tableViewを含む、それを使用するtableViewのセルを忘れずに登録する必要があります。