2017-04-26 70 views
0

你好我試圖在swift 3.0中實現搜索欄,它的部分完成,我沒有得到預期的結果,這裏是我得到的東西這樣快速排序結果集取決於字符串的出現次數

enter image description here

這裏結果是我的控制器

 class MasterViewController: UITableViewController 
     { 
    // MARK: - Properties 
     var detailViewController: DetailViewController? = nil 
    var candies = [Candy]() 
    var filteredCandies = [Candy]() 
    let searchController = UISearchController(searchResultsController: nil) 

// MARK: - Viewcontroller lifecycle 
override func viewDidLoad() 
{ 
    super.viewDidLoad() 
    setupSearchVC() 
    setupModelData() 
    if let splitViewController = splitViewController { 
     let controllers = splitViewController.viewControllers 
     detailViewController = (controllers[controllers.count - 1] as! UINavigationController).topViewController as? DetailViewController 
    } 
} 

override func viewWillAppear(_ animated: Bool) 
{ 
    clearsSelectionOnViewWillAppear = splitViewController!.isCollapsed 
    super.viewWillAppear(animated) 
} 

// MARK: - View setup 
func setupSearchVC() 
{ 
    searchController.searchResultsUpdater = self 
    searchController.dimsBackgroundDuringPresentation = false 
    searchController.searchBar.scopeButtonTitles = ["All", "Chocolate", "Hard", "Other"] 
    searchController.searchBar.delegate = self 
    definesPresentationContext = true 
    tableView.tableHeaderView = searchController.searchBar 
} 


// MARK: - Segues 
override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
{ 
    if segue.identifier == "showDetail" 
    { 
     if let indexPath = tableView.indexPathForSelectedRow 
     { 
      let controller = (segue.destination as! UINavigationController).topViewController as! DetailViewController 
      controller.detailCandy = getDaCorrectCandyNow(row: indexPath.row) 
      controller.navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem 
      controller.navigationItem.leftItemsSupplementBackButton = true 
     } 
    } 
} 

// MARK: - Controller responsibilities 
func setupModelData() 
{ 
    candies = [ 
     Candy(category:"complete", name:"test"), 
     Candy(category:"incomplete", name:"test test"), 

    ] 
} 


func getDaCorrectCandyNow(row: Int) -> Candy 
{ 
    let candy: Candy 
    if searchController.isActive { 
     candy = filteredCandies[row] 
    } else { 
     candy = candies[row] 
    } 
    return candy 
} 

func filterContentForSearchText(_ searchText: String, scope: String = "All") 
{ 
    filteredCandies = candies.filter { candy in 
     let categoryMatch = (scope == "All" ? true : (candy.category == scope)) 
     let searchValueIsNotEmpty = (categoryMatch && candy.name.lowercased().contains(searchText.lowercased()) || candy.category.lowercased().contains(searchText.lowercased())) 
     let searchValueIsEmpty = (searchText == "") 
     return searchValueIsEmpty ? categoryMatch : searchValueIsNotEmpty 
    } 
    tableView.reloadData() 
    } 
    } 

這裏是我的tableview

 override func tableView(_ tableView: UITableView, 
     numberOfRowsInSection section: Int) -> Int 
      { 
      if searchController.isActive { 
     return filteredCandies.count 
      } 
    return candies.count 
} 



func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
{ 
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath) 
    let candy: Candy = getDaCorrectCandyNow(row: indexPath.row) 
    cell.textLabel?.text = candy.name 
    cell.detailTextLabel?.text = candy.category 
    return cell 
} 


// MARK: - Search bar Delegate 
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) 
{ 
    print("*searchBar - ") 
    filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope]) 
} 

// MARK: - Search View Controller Delegate 
public func updateSearchResults(for searchController: UISearchController) 
{ 
    let searchBar = searchController.searchBar 
    print("*updateSearchResults - \(searchBar.text)") 
    let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex] 
    filterContentForSearchText(searchController.searchBar.text!, scope: scope) 
} 
} 

我希望我的結果以no號爲基礎顯示。出現在我的結果集 爲如 如果我在搜索欄 和 搜索「測試」如果我將結果集這樣 集糖果= [ 糖果(類別:「完整」,名稱:「測試」) , 糖果(類別:「不完整」,名稱:「測試」)] 我想糖果(類別:「不完整」,名稱:「測試測試」)首先顯示,因爲它有兩個「測試」項目我如何去做?對不起我的英文,請提前致謝

回答

1

您需要做的是計算每個糖果上的匹配數並在將數據返回到filteredCandies數組之前對數據進行排序。要做到這一點,你需要修改你的過濾器功能。

你可以使用map()函數返回一個包含糖果和匹配計數的元組數組。

從那裏你可以篩選匹配的數量和排序計數上的元組數組。然後,你只需從元組中移除count並僅返回最後一個數組中的糖果。

要計算匹配的數量,可以使用String類型的components()函數。使用搜索字符串作爲components()的分隔符將返回比匹配數量多一個子字符串(因此count - 1將是匹配數)。

這裏有一個如何,你可以使用這種方法寫一個過濾器的例子:

filteredCandies = candies.map 
{ 
    candy in 

    let matchesCategory = scope == "All" || candy.category == scope 
    var matchCount  = matchesCategory ? 1 : 0 

    if matchesCategory && searchText != "" 
    { 
     let lowerSearch = searchText.lowercased() 
     matchCount = candy.name.lowercased().components(separatedBy: lowerSearch).count - 1 
     matchCount += candy.category.lowercased().components(separatedBy: lowerSearch).count - 1 
    } 

    return (candy,matchCount) 
} 
.filter{ $1 > 0 }.sorted{$0.1 > $1.1}.map{$0.0} 
+0

非常感謝你的隊友,就像一個魅力。 –