Sqlite から何万もの単語エントリを検索して UITableView を埋めるギリシャ語辞書アプリがあります。ここで概説されているのと同じ問題の多くに遭遇しています(検索テキストが変更されたときにキーボードの遅延が発生し、検索テキストが変更された場合は検索を中止して再実行する必要があります)、提供されたソリューションはうまく機能します。
私のコード:
func updateSearchResultsForSearchController(searchController: UISearchController) {
if (self.resultSearchController.searchBar.text == "") {
theResultsArray.removeAll(keepCapacity: true)
searchTable.reloadData()
return
}
self.theResultsArray = filter(self.wordArray) {
$0[self.betaNoSymbols].rangeOfString(self.resultSearchController.searchBar.text) != nil
// ($0[self.betaCode] as NSString).containsString(self.resultSearchController.searchBar.text)
}
searchTable.reloadData()
}
現在の例では、1 つのフィールドのみを検索していますが、分音符号の有無にかかわらずギリシャ語、記号の有無にかかわらずベータ コード (音訳された英語) を複数検索したいと考えています。Sqliteをクエリするか、最初に単語リストを配列に配置する方が速いかどうか、またSwiftとiOS 8で別の解決策があるかどうか疑問に思っています.コードを適応させる必要がある場合は、助けていただければ幸いです.
アップデート:
検索を非同期キューに入れましたが、機能しているようです。配列フィルターを使用すると、UISearchBar を何度も編集した後、何らかの理由で検索が機能しなくなったため、Sqlite を使用するようになりました。
let searchQueue = dispatch_queue_create("searchQueue", DISPATCH_QUEUE_SERIAL)
func updateSearchResultsForSearchController(searchController: UISearchController) {
if (self.resultSearchController.searchBar.text == "") {
theResultsArray.removeAll(keepCapacity: true)
searchTable.reloadData()
println("Search field empty.")
return
}
let searchText = self.resultSearchController.searchBar.text
var tempArray = [Row]()
dispatch_async(searchQueue) {
// abort if text changed
if searchText != self.resultSearchController.searchBar.text {
println("Search changed, aborted.")
return
}
// do search
if resultSearchController.searchBar.selectedScopeButtonIndex == 0 {
tempArray = Array(self.liddellQuery.select(self._id, self.greekFullWord).filter(
like("%\(self.resultSearchController.searchBar.text!)%", self.betaNoSymbols)
|| like("%\(self.resultSearchController.searchBar.text!)%", self.betaSymbols)
|| like("%\(self.resultSearchController.searchBar.text!)%", self.greekFullWord)
|| like("%\(self.resultSearchController.searchBar.text!)%", self.greekLowercase)
|| like("%\(self.resultSearchController.searchBar.text!)%", self.greekNoSymbols) println("Searched: \(self.resultSearchController.searchBar.text), results: \(tempArray.count)")
} else {
...
}
// update if search still current
if searchText == self.resultSearchController.searchBar.text {
dispatch_async(dispatch_get_main_queue()) {
self.theResultsArray = tempArray
self.searchTable.reloadData()
}
}
}
}
そのままが最善の方法かどうかはわかりません。また、検索の間には長い遅延があり、検索アイコンを置き換える UIIndicatorView が役立ちます。