2015-08-25 66 views
0

我是Swift的新手,所以要溫和。添加UISearchBarController結果的麻煩TableView

我正在使用Xcode 7 Beta。

我有一個嵌套在NavigationController中的TableViewController。在TableView中,我實現了一個類似於步驟hereUISearchBarUISearchDisplayController。幾乎所有的工作都按預期工作,除了當我鍵入我的搜索條件時,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調用文本更改。

希望我解釋正確。如果我不清楚或錯過了某些內容,請隨時編輯這個問題。

回答

0

所以我最終得到了我想要的功能,並最終回答了我的問題是什麼是正確的方法。事實證明,我正在試圖在一個圓孔中安裝一個方形釘。

我最終做的是完全刪除UISearchDisplayController,而不是創建一個UISearchBar並將其分配給我的self.navigationItem.titleView。這刪除了搜索控制器的一些內置功能,但也給了我一個更簡潔的方式來做我需要做的事情,而不用擔心愚蠢的解決方法。我的代碼看起來大致是

class TableViewController: UISearchBarDelegate { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let searchBar: UISearchBar = UISearchBar() 

     searchBar.placeholder = "Search" 
     searchBar.delegate = self 

     self.navigationItem.titleView = searchBar 

     self.definesPresentationContext = true 
    } 


    func searchBar(searchBar: UISearchBar, textDidChange searchText: String) { 
     timer.invalidate() 

     timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "getResults:", userInfo: searchText, repeats: false) 
    } 

    func searchBarSearchButtonClicked(searchBar: UISearchBar) { 
     searchBar.resignFirstResponder() 
    } 

} 

這種做法得到了我,我一直在尋找(能夠在呼叫時延的API,直到用戶已完成輸入)功能,並且我也能夠刪除一些代碼,這是無關。希望這有助於未來的人。