最後に別の方法を実行しました。メインストーリーボードのテーブルビューからセルを削除し、新しいファイル (xib ファイルを使用) を作成してカスタムセルを作成しました。
カスタム クラス セルのコードは次のとおりです。
class TableCell: UITableViewCell {
@IBOutlet weak var pgrmLabel: UILabel!
@IBOutlet weak var noteLabel: UILabel!
@IBOutlet weak var logoView: UIImageView!
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
}
func setCell(cell: TableCell, pgrmName:String, noteInt:Int, logoName:String){
if let itemName=self.pgrmLabel{
itemName.text=pgrmName
}
if let itemNote=self.noteLabel{
itemNote.text="\(noteInt)"
}
if let itemLogo=self.logoView{
itemLogo.image=UIImage(named: logoName)
if ((itemLogo.image) == nil){
itemLogo.image=UIImage(named: "placeholder.jpg")
}
}
}
}
BaseTableViewController クラスも作成しました。MasterViewController (メイン テーブルビュー) と ResultsTableViewController (これも作成しました) はそれを継承します。
BaseTableViewController:
class BaseTableViewController: UITableViewController {
// MARK: Types
struct Constants {
struct Nib {
static let name = "TableCell"
}
struct TableViewCell {
static let identifier = "cellID"
}
}
// MARK: View Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
let nib = UINib(nibName: Constants.Nib.name, bundle: nil)
// Required if our subclasses are to use: dequeueReusableCellWithIdentifier:forIndexPath:
tableView.registerNib(nib, forCellReuseIdentifier: Constants.TableViewCell.identifier)
}
// MARK:
func configureCell(cell: TableCell, forProgram program: Program) {
cell.setCell(cell, pgrmName: program.name, noteInt: program.note, logoName: program.imageName)
}
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 100
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 100
}
}
マスター ビュー コントローラー:
class MasterViewController: BaseTableViewController, UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, UISearchDisplayDelegate, UISearchResultsUpdating {
struct RestorationKeys {
static let viewControllerTitle = "ViewControllerTitleKey"
static let searchControllerIsActive = "SearchControllerIsActiveKey"
static let searchBarText = "SearchBarTextKey"
static let searchBarIsFirstResponder = "SearchBarIsFirstResponderKey"
}
//controllers
var detailViewController: DetailViewController? = nil
var searchController: UISearchController!
var resultsTableController: ResultsTableViewController!
var restoredState=SearchControllerRestorableState()
//array of programs to display in the tableview
var arrayOfPrograms=[Program]()
struct SearchControllerRestorableState {
var wasActive=false
var wasFirstResponder=false
}
override func awakeFromNib() {
super.awakeFromNib()
if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
self.clearsSelectionOnViewWillAppear = false
self.preferredContentSize = CGSize(width: 320.0, height: 600.0)
}
}
override func viewDidLoad() {
super.viewDidLoad()
//self.navigationItem.leftBarButtonItem = self.editButtonItem()
if let split = self.splitViewController {
let controllers = split.viewControllers
self.detailViewController = controllers[controllers.count-1].topViewController as? DetailViewController
}
self.setUpPrograms()
let tableViewController=navigationController?.viewControllers[0] as MasterViewController
resultsTableController=ResultsTableViewController()
resultsTableController.tableView.delegate=self
searchController=UISearchController(searchResultsController: resultsTableController)
searchController.searchResultsUpdater=self
searchController.searchBar.sizeToFit()
tableView.tableHeaderView=searchController.searchBar
searchController.delegate=self
searchController.dimsBackgroundDuringPresentation=false
searchController.searchBar.delegate=self
definesPresentationContext=true
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
// Restore the searchController's active state.
if restoredState.wasActive {
searchController.active = restoredState.wasActive
restoredState.wasActive = false
if restoredState.wasFirstResponder {
searchController.searchBar.becomeFirstResponder()
restoredState.wasFirstResponder = false
}
}
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
searchBar.resignFirstResponder()
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var selectedProgram:Program
if tableView == self.tableView {
selectedProgram=arrayOfPrograms[indexPath.row]
}
else{
selectedProgram=resultsTableController.filteredPrograms[indexPath.row]
}
let detailViewController=DetailViewController.forProgram(selectedProgram)
navigationController!.pushViewController(detailViewController, animated: true)
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
// MARK: - Table View
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayOfPrograms.count
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
let searchResults=arrayOfPrograms
// Strip out all the leading and trailing spaces.
let whitespaceCharacterSet = NSCharacterSet.whitespaceCharacterSet()
let strippedString = searchController.searchBar.text.stringByTrimmingCharactersInSet(whitespaceCharacterSet)
let searchItems = strippedString.componentsSeparatedByString(" ") as [String]
// Build all the "AND" expressions for each value in the searchString.
var andMatchPredicates = [NSPredicate]()
for searchString in searchItems {
// Each searchString creates an OR predicate for: name, yearIntroduced, introPrice.
//
// Example if searchItems contains "iphone 599 2007":
// name CONTAINS[c] "iphone"
// name CONTAINS[c] "599", yearIntroduced ==[c] 599, introPrice ==[c] 599
// name CONTAINS[c] "2007", yearIntroduced ==[c] 2007, introPrice ==[c] 2007
//
var searchItemsPredicate = [NSPredicate]()
// Name field matching.
var lhs = NSExpression(forKeyPath: "name")
var rhs = NSExpression(forConstantValue: searchString)
var finalPredicate = NSComparisonPredicate(leftExpression: lhs, rightExpression: rhs, modifier: .DirectPredicateModifier, type: .ContainsPredicateOperatorType, options: .CaseInsensitivePredicateOption)
searchItemsPredicate.append(finalPredicate)
// Channel field matching.
lhs = NSExpression(forKeyPath: "channel")
rhs = NSExpression(forConstantValue: searchString)
finalPredicate = NSComparisonPredicate(leftExpression: lhs, rightExpression: rhs, modifier: .DirectPredicateModifier, type: .ContainsPredicateOperatorType, options: .CaseInsensitivePredicateOption)
searchItemsPredicate.append(finalPredicate)
// Add this OR predicate to our master AND predicate.
let orMatchPredicates = NSCompoundPredicate.orPredicateWithSubpredicates(searchItemsPredicate)
andMatchPredicates.append(orMatchPredicates)
}
// Match up the fields of the Product object.
let finalCompoundPredicate = NSCompoundPredicate.andPredicateWithSubpredicates(andMatchPredicates)
let filteredResults = searchResults.filter { finalCompoundPredicate.evaluateWithObject($0) }
// Hand over the filtered results to our search results table.
let resultsController = searchController.searchResultsController as ResultsTableViewController
resultsController.filteredPrograms = filteredResults
resultsController.tableView.reloadData()
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(Constants.TableViewCell.identifier, forIndexPath: indexPath) as TableCell
let program=arrayOfPrograms[indexPath.row]
configureCell(cell, forProgram: program)
return cell
}
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return false
}
override func encodeRestorableStateWithCoder(coder: NSCoder) {
super.encodeRestorableStateWithCoder(coder)
// Encode the title.
coder.encodeObject(navigationItem.title!, forKey:RestorationKeys.viewControllerTitle)
// Encode the search controller's active state.
coder.encodeBool(searchController.active, forKey:RestorationKeys.searchControllerIsActive)
// Encode the first responser status.
coder.encodeBool(searchController.searchBar.isFirstResponder(), forKey:RestorationKeys.searchBarIsFirstResponder)
// Encode the search bar text.
coder.encodeObject(searchController.searchBar.text, forKey:RestorationKeys.searchBarText)
}
override func decodeRestorableStateWithCoder(coder: NSCoder) {
super.decodeRestorableStateWithCoder(coder)
// Restore the title.
if let decodedTitle = coder.decodeObjectForKey(RestorationKeys.viewControllerTitle) as? String {
title = decodedTitle
}
else {
fatalError("A title did not exist. In your app, handle this gracefully.")
}
// Restore the active state:
// We can't make the searchController active here since it's not part of the view
// hierarchy yet, instead we do it in viewWillAppear.
//
restoredState.wasActive = coder.decodeBoolForKey(RestorationKeys.searchControllerIsActive)
// Restore the first responder status:
// Like above, we can't make the searchController first responder here since it's not part of the view
// hierarchy yet, instead we do it in viewWillAppear.
//
restoredState.wasFirstResponder = coder.decodeBoolForKey(RestorationKeys.searchBarIsFirstResponder)
// Restore the text in the search field.
searchController.searchBar.text = coder.decodeObjectForKey(RestorationKeys.searchBarText) as String
}
}
ResultsTableViewController
class ResultsTableViewController: BaseTableViewController {
var filteredPrograms=[Program]()
override func viewDidLoad() {
super.viewDidLoad()
println("results table view")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
println("results table view nb of raws in section")
return filteredPrograms.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//let cell=tableView.dequeueReusableCellWithIdentifier(Constants.TableViewCell.identifier) as TableCell!
let cell = tableView.dequeueReusableCellWithIdentifier(Constants.TableViewCell.identifier, forIndexPath: indexPath) as TableCell
let program = filteredPrograms[indexPath.row]
configureCell(cell, forProgram: program)
return cell
}
}