Я новичок в Swift, поэтому будьте нежны.Проблемы с населением UISearchBarController Results TableView
В настоящее время я использую бета-версию Xcode 7.
У меня есть TableViewController, вложенный в NavigationController. В TableView я реализовал UISearchBar
и UISearchDisplayController
, аналогично шагам here. Практически все работает так, как ожидалось, за исключением случаев, когда я набираю критерии поиска, представление таблицы результатов для UISearchDisplayController
не заполняется. Когда я ударил Отмена при поиске, результаты были заполнены в начальном виде таблицы.
Учебник, с которым я связан, предварительно заполняет список элементов, и панель поиска фильтрует эти элементы. Мой подход отличается от того, что я заполняю поиск из внешнего API.
Мой вопрос два раза:
а) как я правильно заполнить TableView результаты?
b) два TableView кажутся избыточными, и я не чувствую, что первое необходимо (может быть, неправильно). Каков правильный способ достижения этой функциональности? В идеале я хотел бы разместить UISearchBar
в навигационном элементе, поэтому он живет в UINavigationBar
, но у меня были проблемы с поиском ресурсов для этого.
import UIKit
import Alamofire
import SwiftyJSON
import Foundation
class DSTableViewController: UITableViewController, UISearchBarDelegate, UISearchDisplayDelegate {
var songs: [Song] = []
var timer: NSTimer = NSTimer()
func getSongs(timer: NSTimer!) {
let searchTerm = timer.userInfo as! String
self.title = "Results for \(searchTerm)"
// logic to switch service; need to eventually move this to an interface
// or move this code inside a rest API, and then into an interface
// URL encode the search term
let searchTermEncoded = searchTerm.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
// create the url for the web request
let uri: String = "https://api.spotify.com/v1/search?q=\(searchTermEncoded!)&type=artist,album,track"
// call to Spotify API
Alamofire
.request(.GET, uri)
.response { request, response, data, error in
let json = JSON(data: data!)
print(json["tracks"]["items"].count);
print(json["tracks"]["items"])
for var i = 0; i < json["tracks"]["items"].count; i++ {
let data = json["tracks"]["items"][i]
// return the object list
let song = Song()
song.title = data["name"].string!
song.album = data["album"]["name"].string!
song.artist = data["artists"][0]["name"].string!
self.songs += [song]
}
dispatch_async(dispatch_get_main_queue()) {
self.tableView!.reloadData()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// 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 searchDisplayController(controller: UISearchDisplayController, shouldReloadTableForSearchString searchString: String?) -> Bool {
timer.invalidate()
timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: Selector("getSongs:"), userInfo: searchString, repeats: false)
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 Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return songs.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("SongCell", forIndexPath: indexPath)
let song = songs[indexPath.row]
cell.textLabel?.text = song.title
cell.detailTextLabel?.text = song.artist + " - " + song.album
cell.imageView?.image = song.albumImage
return cell
}
}
Когда я звоню
func searchDisplayController(controller: UISearchDisplayController, shouldReloadTableForSearchString searchString: String?) -> Bool {
self.getSongs(searchString)
return true
}
Я могу правильно заполнить мнение, но я хотел бы иметь задержку, так что я не делаю вызов API каждый раз, когда текст изменяется ,
Надеюсь, я правильно это объяснил. Пожалуйста, не стесняйтесь редактировать вопрос, если я не понял или пропустил что-то.