【问题标题】:Add an Index to a searchBar向 searchBar 添加索引
【发布时间】:2015-11-18 14:04:58
【问题描述】:

需要帮助来更正此代码。
我有一个带有餐厅名称和地址的 coredata 应用程序,有一个搜索栏,它正在运行。我要添加的是索引和索引标题,如下图所示(箭头)。
任何帮助都非常受欢迎。提前致谢。

import UIKit
import CoreData

class DictionaryTableViewController: UITableViewController, NSFetchedResultsControllerDelegate, UISearchResultsUpdating
{
    var searchController:UISearchController!
    var searchResults:[Dictionary] = []

    private var dictionaryItems:[Dictionary] = []
    var fetchResultController:NSFetchedResultsController!

    override func viewDidLoad() {
        super.viewDidLoad()

    if let managedObjectContext = (UIApplication.sharedApplication().delegate as? AppDelegate)?.managedObjectContext {

            let fetchRequest = NSFetchRequest(entityName: "DictionaryEntity")
            do {
                dictionaryItems = try managedObjectContext.executeFetchRequest(fetchRequest) as! [Dictionary]
            } catch {
                print("Failed to retrieve record")
                print(error)
            }
        }

    searchController = UISearchController(searchResultsController: nil)
        tableView.tableHeaderView = searchController.searchBar
        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false

           tableView.estimatedRowHeight = 30.0
        tableView.rowHeight = UITableViewAutomaticDimension
    }


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

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 26
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        if searchController.active {
            return searchResults.count
        } else {
            return dictionaryItems.count
        }
    }

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

        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! DictionaryTableViewCell

        // Configure the cell...
        cell.wordLabel.text = dictionaryItems[indexPath.row].word
        cell.definitionSmallLabel.text = dictionaryItems[indexPath.row].definition

    let dictionary = (searchController.active) ? searchResults[indexPath.row]: dictionaryItems[indexPath.row]

        // Configure the cell...
        cell.wordLabel.text = dictionary.word
        cell.definitionSmallLabel.text = dictionary.definition
        return cell
    }
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? 
    {
        return "dictionaryItems\(section)"
    }

    override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {

           if searchController.active{
            return false
        }else{
            return true
        }
    }


override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "showDictionaryDetail" {
            if let indexPath = tableView.indexPathForSelectedRow {
                let destinationController = segue.destinationViewController as! DictionaryDetailViewController
                destinationController.dictionary = (searchController.active) ? searchResults[indexPath.row] : dictionaryItems[indexPath.row]
                searchController.active = false
            }
        }
    }

        func updateSearchResultsForSearchController(searchController:
            UISearchController) {
                if let searchText = searchController.searchBar.text {
                    filterContentForSearchText(searchText)
                    tableView.reloadData()
                }
        }

        func filterContentForSearchText(searchText: String) {
            searchResults = dictionaryItems.filter({ (dictionary:Dictionary) -> Bool in
                let wordMatch = dictionary.word!.rangeOfString(searchText, options:
                    NSStringCompareOptions.CaseInsensitiveSearch)
                return wordMatch != nil
            })
        }
}



我想在我的表视图中拥有的是索引(左侧的箭头)和索引标题(右侧的箭头)。

【问题讨论】:

  • 您遇到的错误是什么?
  • 错误:方法没有覆盖其超类中的任何方法.......................覆盖 func tableview( tableView: UITableView, titleForHeaderSection 部分: Int) -> String? { return "dictionaryItems(section)" }
  • 你打错了:方法是titleForHeaderInSection(注意In)。
  • @ pbasdf 谢谢这是我的错误,但错误仍然相同,我正在尝试在右侧有一个带有字母的部分和索引,就像 iphone 上的联系人一样。我认为代码有问题... :(

标签: uitableview core-data swift2 uisearchbar xcode7


【解决方案1】:

titleForHeaderInSection

的覆盖函数中有错别字

这里是更正的,注意tableView中的v是大写的:(复制粘贴我的代码)

override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

}

我建议使用 Xcode 的自动完成功能。这样,您就不会陷入像这样的隐蔽错误中。

更新: 您还需要提供这两种方法来查看节标题和节索引标题。

override func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
    return ["A", "B", "C"]
}

override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return "A title for section: \(section)"
}

试试下面的代码:

class TableViewController: UITableViewController {

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 9
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return 9
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)

    // Configure the cell...
    cell.textLabel?.text = "\(indexPath.section+1)\(indexPath.row+1)"

    return cell
}

override func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
    return ["A", "C", "B"]
}

override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return "SECTION \(section+1)"
}

}

【讨论】:


  • 您好,我修正了我的拼写错误,但仍然没有显示索引和索引标题。任何其他提示? :)
  • @Jade,您还需要提供 sectionIndexTitlesForTableView 才能查看索引。
  • 我还使用示例代码更新了我的答案,该示例代码演示了它是如何工作的。我对此进行了测试,它可以在运行 iOS 9.0 的 iPhone 6 上运行。如果它不起作用,请告诉我
  • 好的,有几件事:1.确保节数与节索引标题数匹配(在右侧),它按顺序工作,所以如果你提供的少,它会导航到错误部分。 2. 因为您自己提供,所以您在每个部分都获得了整个数据库;在函数 numberOfRowsInSection 中,UITableViewDataSource 询问该特定部分的项目数,您的工作是在 cellForRowAtIndexPath 中为其提供正确的数字和正确的表格视图单元格。
  • 因此,如果您想按字母顺序进行,请根据 numberOfRowsInSection 中的节号过滤掉您的数组。例如,在 A 部分,返回数据库中以字母 'A' 开头的项目数,而不是返回整个数组的长度。
【解决方案2】:

一种方法是使用 NSFetchedResultsController 上的内置属性。其中最重要的部分是设置 sectionNameKeyPath(它应该是包含标题的托管对象属性)。

private var frc: NSFetchedResultsController? = nil
private lazy var fetchedResultsController:NSFetchedResultsController = {

        if self.frc != nil {
            return self.frc!
        }
        //grab your managed object context
        let moc = dbStore.sharedInstance.managedObjectContext


        let fetchRequest = NSFetchRequest(entityName: "Transaction")
        fetchRequest.fetchBatchSize = 30
        fetchRequest.resultType = NSFetchRequestResultType.ManagedObjectResultType
        let sortDescriptorByTimeStamp =  NSSortDescriptor(key: "timeStamp", ascending: true)
        fetchRequest.sortDescriptors = [sortDescriptorByTimeStamp]

        //in-memory cache when cachename is nil, delegate is non-nil
        //note the sectionNameKeyPath requires that I have a related category object with the categoryName attribute on my Transaction managed object
        let nfrc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: "category.categoryName", cacheName: nil)

        self.frc = nfrc
        do
        {
            try self.frc!.performFetch()
        } catch let e as NSError {
            fatalError(e.localizedDescription)
        }

        return self.frc!
    }()

章节标题

要获取章节标题,您需要实现此方法。

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        let sectionTitle = self.fetchedResultsController.sections?[section].name ?? "No Category Titles"
        return sectionTitle

}

表索引

要设置索引,请实施以下方法。

func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {

        return self.fetchedResultsController.sectionIndexTitles ?? [""]

}

单击时请注意快速帮助文档 部分索引标题。 部分索引标题的数组。默认 实现返回通过调用创建的数组 sectionIndexTitleForSectionName:在所有已知部分上。你应该 如果要为 部分索引。只有在使用节索引时才需要此方法。

来源

如果您想在上下文中查看此内容,要了解如何以这种方式使用 NSFetchedResultsController 的要点,您可以查看my sample at this location

替代品(数组/字典)

还有其他一些关于如何从数组和字典构建索引的教程(但我推荐上述方法作为最简单的方法)。

替代实现

注意:本节中的代码来自 Alternate Tutorial #1

 // `UIKit` convenience class for sectioning a table
    let collation = UILocalizedIndexedCollation.currentCollation()
        as UILocalizedIndexedCollation
....
/* section headers
       appear above each `UITableView` section */
    override func tableView(tableView: UITableView,
        titleForHeaderInSection section: Int)
        -> String {
        // do not display empty `Section`s
        if !self.sections[section].users.isEmpty {
            return self.collation.sectionTitles[section] as String
        }
        return ""
    }

    /* section index titles
       displayed to the right of the `UITableView` */
    override func sectionIndexTitlesForTableView(tableView: UITableView)
        -> [AnyObject] {
        return self.collation.sectionIndexTitles
    }

    override func tableView(tableView: UITableView,
        sectionForSectionIndexTitle title: String,
        atIndex index: Int)
        -> Int {
        return self.collation.sectionForSectionIndexTitleAtIndex(index)
    }

【讨论】:

  • 所以我的代码不能用于索引,我必须改成你的。我正在从 appcoda 教程中寻找要添加到此代码中的内容:(
  • @Manolo - 试试 NSFRC,我想你会发现它是一个更清洁的解决方案。请参阅我的源代码(上面的链接),了解如何在使用 NSFRC 时处理典型的 tableview 委托/数据源方法。我认为本教程使用的是较旧的方法,NSFRC 更快,更易于使用,效率更高。
  • 感谢您的宝贵时间,但我的知识不足以进行所有这些更改,我想知道是否有人可以帮助我使用本教程中的代码并告诉我为什么我不能让它工作。
  • @Manolo 您是否在代码的某个地方发布了一个单独的问题?如果您可以分享,那么我可以协助您解决具体问题。
  • @Tommie C. 我没有其他问题,但这里是教程中的代码,我正在尝试更改和学习...dl.dropboxusercontent.com/u/14313867/CockpitDictionary.zip
猜你喜欢
  • 2014-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-04
  • 2018-08-24
  • 2018-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多