uitableview - 具有多个原型(prototype)单元格的 Swift 中用于 tableView 的 UISearchBar

标签 uitableview swift runtime-error uisearchbar

我需要为我的动态 tableView 实现一个搜索栏。在 http://www.raywenderlich.com/76519/add-table-view-search-swift 有一个例子用于 Swift 中的搜索栏。该示例仅显示了如何对一个原型(prototype)电池执行此操作。我有多个。

我尝试用以下方法自己实现:

class MediaItem{
    var name: String
    init(name: String){
        self.name = name
    }
}

class Movie: MediaItem{
    var director: String
    init(name:String, director: String){
        self.director = director
        super.init(name: name)
    }
}


class Song: MediaItem{
    var artist: String
    init(name: String, artist: String){
        self.artist = artist
        super.init(name: name)
    }

//
//  ItemsTableViewController.swift
//  SearchBarTest1
//
//  Created by Josh Kallus on 12/7/14.
//  Copyright (c) 2014 JMKLABS. All rights reserved.
//

import UIKit

class ItemsTableViewController: UITableViewController, UISearchBarDelegate, UISearchDisplayDelegate {

var library = [MediaItem]()
var filteredLibrary = [MediaItem]()

override func viewDidLoad() {
    super.viewDidLoad()


    self.library = [
        Movie(name: "Casablanca", director: "Michael Curtiz"),
        Song(name: "Blue Suede Shoes", artist: "Elvis Presley"),
        Movie(name: "Citizen Kane", director: "Orson Welles"),
        Song(name: "The One And Only", artist: "Chesney Hawkes"),
        Song(name: "Never Gonna Give You Up", artist: "Rick Astley")]

    self.tableView.reloadData()

    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem()
}

func filterContentForSearchText(searchText: String){
    self.filteredLibrary = self.library.filter({(mediaItem: MediaItem) -> Bool in
        let stringMatch = mediaItem.name.rangeOfString(searchText)
        return (stringMatch != nil)
    })
}


func searchDisplayController(controller: UISearchDisplayController!, shouldReloadTableForSearchString searchString: String!) -> Bool {
    self.filterContentForSearchText(searchString)
    return true
}

func searchDisplayController(controller: UISearchDisplayController!, shouldReloadTableForSearchScope searchOption: Int) -> Bool {
    self.filterContentForSearchText(self.searchDisplayController!.searchBar.text)
    return true
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete method implementation.
    // Return the number of rows in the section.
    if tableView == self.searchDisplayController!.searchResultsTableView {
        return self.filteredLibrary.count
    } else {
        return self.library.count
    }
}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell: UITableViewCell
    // Configure the cell...
    if tableView == self.searchDisplayController!.searchResultsTableView{


        //let searchText = self.searchDisplayController!.searchBar.text
        //filterContentForSearchText(searchText)


        if let song = filteredLibrary[indexPath.row] as? Song{
            cell = tableView.dequeueReusableCellWithIdentifier("songCell") as UITableViewCell
            //cell = self.searchDisplayController.searchResultsTableView.dequeueReusableCellWithIdentifier("songCell") as UITableViewCell
            cell.textLabel?.text = song.name
            cell.detailTextLabel?.text = song.artist
        }

        else{
            let movie = filteredLibrary[indexPath.row] as Movie

            cell = tableView.dequeueReusableCellWithIdentifier("movieCell") as UITableViewCell
            //cell = self.searchDisplayController!.searchResultsTableView.dequeueReusableCellWithIdentifier("movieCell") as UITableViewCell
            cell.textLabel?.text = movie.name
            cell.detailTextLabel?.text = movie.director
        }
    }

    else{
        if let song = library[indexPath.row] as? Song{
            cell = tableView.dequeueReusableCellWithIdentifier("songCell", forIndexPath: indexPath) as UITableViewCell
            cell.textLabel?.text = song.name
            cell.detailTextLabel?.text = song.artist
        }

        else{
            let movie = library[indexPath.row] as Movie
            cell = tableView.dequeueReusableCellWithIdentifier("movieCell", forIndexPath: indexPath) as UITableViewCell
            cell.textLabel?.text = movie.name
            cell.detailTextLabel?.text = movie.director
        }
    }

    return cell
}

目前我收到错误“ fatal error :在展开可选值时意外发现 nil”

在行:cell = tableView.dequeueReusableCellWithIdentifier("songCell") as UITableViewCell

最佳答案

您需要注册一个classnib file对于您正在使用的每个标识符的 TableView 单元格。执行此操作的好地方是 viewDidLoad:

if let tableView = self.searchDisplayController?.searchResultsTableView {
  tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier:"songCell")
  tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier:"movieCell")
}

关于uitableview - 具有多个原型(prototype)单元格的 Swift 中用于 tableView 的 UISearchBar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27350793/

相关文章:

ios - AutoLayout 的 systemLayoutSizeFittingSize 仅适用于 UILabels?

iphone - 对 uitableviewcell 背景颜色进行动画更改

uinavigationbar - 在swift中设置navigationBar背景图片

ios - 向其添加本地化后加载 JSON 失败 Swift 3

swift - 当行包含按钮时禁用表单行选择

ios - 通过向后滑动关闭 UISwipeActionsConfiguration

ios - 如何在 cellforrowatindexpath 之后更新自定义表格单元格中的 UIButton 图像?

java - 运行我的 JAVA 程序时出现运行时错误

java - 成品中的 printStackTrace()。什么时候以及为什么?

c++ - 类中指针访问私有(private)数组的声明及内存分配