【问题标题】:TableView search in SwiftSwift 中的 TableView 搜索
【发布时间】:2017-05-30 12:21:36
【问题描述】:

我有两个数组:FirstTableArray(包括品牌名称)和 SecondTableArray(包括型号)。

我想添加搜索,通过它可以通过部分名称找到手机型号。

import UIKit
import MessageUI

class FirstTableViewController: UITableViewController {

    var FirstTableArray = [String]()
    var SecondTableArray = [SecondTable]()

override func viewDidLoad() {

    super.viewDidLoad()

    self.navigationController?.navigationBar.isTranslucent = false
    self.navigationController?.navigationBar.barStyle = .black
    self.navigationController?.navigationBar.tintColor = UIColor.white

// First Table Array

    FirstTableArray = ["Apple", "Samsung"]

// Second Table Array

    SecondTableArray = [
    SecondTable(SecondTitle: ["iPhone 5s", "iPhone 6", "iPhone 6s"]),
    SecondTable(SecondTitle: ["Galaxy S4", "Galaxy S5", "Galaxy S6"]), 
    ]   
    }

 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
    return FirstTableArray.count
    }

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let Cell = self.tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as UITableViewCell
    Cell.textLabel?.text = FirstTableArray[(indexPath as NSIndexPath).row]
    return Cell
    }

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let indexPath : IndexPath = self.tableView.indexPathForSelectedRow!
    let DestViewController = segue.destination as! SecondTableViewController
    let SecondTableArrayTwo = SecondTableArray[(indexPath as NSIndexPath).row]
    DestViewController.SecondTableArray = SecondTableArrayTwo.SecondTitle
    } 
}

你能帮我解决这个问题吗?

【问题讨论】:

    标签: arrays swift uitableview tableview uisearchbar


    【解决方案1】:

    我建议实现 UISearchBar 并将您的类作为委托添加到 UISearchBar,然后在委托方法中,您可以获取搜索栏文本并在数据源上执行搜索,然后相应地重新加载 tableview 数据

    编辑:您可以使用本教程了解如何在 UITableView 上实现 UISearchBar https://www.raywenderlich.com/472-uisearchcontroller-tutorial-getting-started

    【讨论】:

      【解决方案2】:

      我今天也在做同样的事情,发现这个教程很容易理解:https://github.com/codepath/ios_guides/wiki/Search-Bar-Guide

      它将带您完成在 Interface Builder 中添加搜索栏、设置委托以及包含过滤结果的方法的步骤。


      为用户提供一种搜索项目集合的方法是 iOS 项目中相当常见的任务。实现搜索行为的标准接口是搜索栏。

      使用搜索栏有几种常用方法:

      • 直接使用 UISearchBar。这是最简单的使用方式 UISearchBars。如果您想设计,这可以非常灵活 并编写您自己的搜索界面,但不提供 许多内置功能与其他方法一样。

      • 使用 UISearchDisplayController 来帮助管理搜索界面。 UISearchDisplayController 允许您呈现标准搜索 带有内置动画的界面。此方法强制您显示 表格视图中的搜索结果。 - 已弃用

      • 使用 UISearchController 来帮助管理搜索界面。
        UISearchController 是一个较新的控制器(仅适用于 iOS 8+)
        这可以帮助您使用任何类型的视图呈现搜索界面
        显示搜索结果。

      本指南涵盖了使用这些类的基本知识。这些类都没有真正实现查找与给定查询字符串匹配的项目的“搜索”行为,因为确定哪些对象匹配将随域特定用例而变化(例如,当搜索“人”时,您可能只想匹配他们的名称,而您在搜索电子邮件时可能需要全文预索引搜索)。您必须自己实现任何搜索/过滤行为。

      直接使用 UISearchBars

      在其核心,搜索栏只不过是一个美化的文本字段,其中包含一个范围控件、一些动画和几个按钮。每个搜索栏都有一个委托,让您有机会响应用户操作。最重要的委托方法是:

      • textDidChange - 大多数情况下,您会通过以下方式响应此事件 在用户键入时更新显示的搜索结果集 出一个查询
      • searchBarSearchButtonClicked - 在某些情况下如果搜索操作 速度很慢(例如,需要进行缓慢的 API 调用),您需要等待 直到用户在更新搜索之前点击搜索按钮 结果。

      搜索表格的示例

      我们从一个带有基本 UITableView 的单视图应用程序开始。您可以像添加任何其他控件一样添加 UISearchBar,方法是在界面构建器中将一个 UISearchBar 拖到您的视图控制器或以编程方式添加它。

      搜索栏的delegate属性必须设置为实现UISearchBarDelegate的对象。通常,您让视图控制器实现 UISearchBarDelegate 并在 viewDidLoad 方法中设置 searchBar.delegate = self。

      实现搜索行为的代码如下。我们维护了一个额外的数组过滤数据来表示与我们的搜索文本匹配的数据行。当搜索文本发生变化时,我们会更新filteredData 并重新加载我们的表格。

      class ViewController: UIViewController, UITableViewDataSource, UISearchBarDelegate {
          @IBOutlet weak var tableView: UITableView!
          @IBOutlet weak var searchBar: UISearchBar!
      
      let data = ["New York, NY", "Los Angeles, CA", "Chicago, IL", "Houston, TX",
          "Philadelphia, PA", "Phoenix, AZ", "San Diego, CA", "San Antonio, TX",
          "Dallas, TX", "Detroit, MI", "San Jose, CA", "Indianapolis, IN",
          "Jacksonville, FL", "San Francisco, CA", "Columbus, OH", "Austin, TX",
          "Memphis, TN", "Baltimore, MD", "Charlotte, ND", "Fort Worth, TX"]
      
      var filteredData: [String]!
      
      override func viewDidLoad() {
          super.viewDidLoad()
          tableView.dataSource = self
          searchBar.delegate = self
          filteredData = data
      }
      
      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
          let cell = tableView.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as UITableViewCell
          cell.textLabel?.text = filteredData[indexPath.row]
          return cell
      }
      
      func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
          return filteredData.count
      }
      
      // This method updates filteredData based on the text in the Search Box
      func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
          // When there is no text, filteredData is the same as the original data
          // When user has entered text into the search box
          // Use the filter method to iterate over all items in the data array
          // For each item, return true if the item should be included and false if the
          // item should NOT be included
          filteredData = searchText.isEmpty ? data : data.filter({(dataString: String) -> Bool in
              // If dataItem matches the searchText, return true to include it
              return dataString.range(of: searchText, options: .caseInsensitive) != nil
          })
      
          tableView.reloadData()
      }
      }
      

      这是运行时的样子。请注意,搜索结果显示在同一个表格中,并没有呈现单独的搜索界面。

      搜索集合视图的示例

      由于 UISearchBar 非常简单,它可以与任意视图组合来构建您自己的搜索界面。这是它与集合视图配对时的样子。

      这方面的代码与表格视图的情况基本相同。

      取消搜索并隐藏键盘

      一旦用户点击搜索栏,键盘就会出现,并且您会注意到当您点击 X 时它不会消失。您可以在用户点击搜索栏和点击取消时显示取消按钮, 隐藏键盘。

      UISearchBarDelegate 有一个漂亮的 searchBarTextDidBeginEditing 方法,当用户开始编辑搜索文本时会调用该方法。您可以在该方法中显示取消按钮:

      func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
              self.searchBar.showsCancelButton = true
      }
      

      当用户点击取消按钮时,委托的 searchBarCancelButtonClicked 方法被调用。此时,您可以隐藏取消按钮,清除搜索栏中的现有文本并隐藏键盘,如下所示:

      func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
              searchBar.showsCancelButton = false
              searchBar.text = ""
              searchBar.resignFirstResponder()
      }
      

      使用 UISearchControllers (iOS 8+)

      一种管理搜索界面显示的新方法(仅适用于 iOS 8 及更高版本)是通过 UISearchController。此控制器处理一些为您呈现单独的搜索界面的逻辑和动画,同时仍允许您指定搜索结果的显示方式。

      搜索表格的示例

      目前在 UISearchController 的 Interface Builder 对象库中没有内置对象。创建一个的最简单方法是以编程方式进行。这也创建了一个 UISearchBar 并将搜索控制器的 searchBar 属性设置为它。您可以通过编程方式将此搜索栏添加到您的视图层次结构中。

      为了更新您的搜索结果,您必须实现 UISearchResultsUpdating 协议并设置搜索控制器的 searchResultsUpdater 属性。

      你不需要实现 UISearchControllerDelegate,除非你需要挂钩到搜索界面展示周围的事件。

      把它们放在一起,代码看起来像这样。请注意,我们必须从 updateSearchResultsForSearchController 的搜索栏中读取搜索文本。需要注意的另一件事是我们将此视图控制器的定义PresentationContext 属性设置为true。这意味着搜索控制器在呈现搜索界面时应该使用这个视图控制器的框架(与根视图控制器相反)。在这种情况下,这意味着搜索界面将在载体栏上方展开。

      class ViewController: UIViewController, UITableViewDataSource, UISearchResultsUpdating {
          @IBOutlet weak var tableView: UITableView!
      
      let data = ["New York, NY", "Los Angeles, CA", "Chicago, IL", "Houston, TX",
          "Philadelphia, PA", "Phoenix, AZ", "San Diego, CA", "San Antonio, TX",
          "Dallas, TX", "Detroit, MI", "San Jose, CA", "Indianapolis, IN",
          "Jacksonville, FL", "San Francisco, CA", "Columbus, OH", "Austin, TX",
          "Memphis, TN", "Baltimore, MD", "Charlotte, ND", "Fort Worth, TX"]
      
      var filteredData: [String]!
      
      var searchController: UISearchController!
      
      override func viewDidLoad() {
          super.viewDidLoad()
      
          tableView.dataSource = self
          filteredData = data
      
          // Initializing with searchResultsController set to nil means that
          // searchController will use this view controller to display the search results
          searchController = UISearchController(searchResultsController: nil)
          searchController.searchResultsUpdater = self
      
          // If we are using this same view controller to present the results
          // dimming it out wouldn't make sense. Should probably only set
          // this to yes if using another controller to display the search results.
          searchController.dimsBackgroundDuringPresentation = false
      
          searchController.searchBar.sizeToFit()
          tableView.tableHeaderView = searchController.searchBar
      
          // Sets this view controller as presenting view controller for the search interface
          definesPresentationContext = true
      }
      
      func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
          let cell = tableView.dequeueReusableCellWithIdentifier("TableCell") as UITableViewCell
          cell.textLabel?.text = filteredData[indexPath.row]
          return cell
      }
      
      func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
          return filteredData.count
      }
      
      func updateSearchResultsForSearchController(searchController: UISearchController) {
          if let searchText = searchController.searchBar.text {
              filteredData = searchText.isEmpty ? data : data.filter({(dataString: String) -> Bool in
                  return dataString.rangeOfString(searchText, options: .CaseInsensitiveSearch) != nil
              })
      
              tableView.reloadData()
          }
      }
      }
      

      这是运行时的样子。请注意,与搜索显示控制器示例不同,我们使用相同的表视图来显示搜索结果,而不是覆盖单独的表视图。但是,与仅使用搜索栏时不同的是,在转换到搜索界面时,我们仍然拥有内置动画。

      此外,当您使用此功能时,您还可以在用户免费点击取消按钮时显示“取消”按钮并隐藏键盘。

      搜索集合视图的示例

      我们可以很容易地使用搜索控制器来搜索集合视图。我们仍然有一个搜索界面的展示,但与使用搜索显示控制器时不同的是,我们不限于使用表格视图来显示搜索结果。

      此代码几乎与搜索上面的表格视图时相同。唯一显着的区别是我们必须在搜索栏的界面构建器中引入占位符视图,因为将搜索控制器的搜索栏放置在集合视图的补充视图中仍然存在一些怪癖。

      class ViewController: UIViewController, UICollectionViewDataSource, UISearchResultsUpdating {
          @IBOutlet weak var collectionView: UICollectionView!
          @IBOutlet weak var searchBarPlaceholder: UIView!
          ...
          override func viewDidLoad() {
              ...
              searchController.searchBar.sizeToFit()
              searchBarPlaceholder.addSubview(searchController.searchBar)
              automaticallyAdjustsScrollViewInsets = false
              definesPresentationContext = true
          }
      
          ...
      }
      

      导航视图中的搜索栏

      一个常见的要求是将搜索栏放在导航栏内。

      这可以在您的视图控制器的 viewDidLoad 中以编程方式进行配置,如下所示。

      直接使用搜索栏时:

      // create the search bar programatically since you won't be
      // able to drag one onto the navigation bar
      searchBar = UISearchBar()
      searchBar.sizeToFit()
      
      // the UIViewController comes with a navigationItem property
      // this will automatically be initialized for you if when the
      // view controller is added to a navigation controller's stack
      // you just need to set the titleView to be the search bar
      navigationItem.titleView = searchBar
      

      使用搜索显示控制器:

      searchDisplayController?.displaysSearchBarInNavigationBar = true
      

      使用搜索控制器:

      searchController.searchBar.sizeToFit()
      navigationItem.titleView = searchController.searchBar
      
      // By default the navigation bar hides when presenting the
      // search interface.  Obviously we don't want this to happen if
      // our search bar is inside the navigation bar.
      searchController.hidesNavigationBarDuringPresentation = false
      

      【讨论】:

      • 在 Swift 3+ 中,用于更新的协议 UISearchResultsUpdating 函数的签名已更改:func updateSearchResults(for searchController: UISearchController)
      • 对我来说,当我在搜索栏文本中添加空格时它不起作用,先生有什么解决方案吗?谢谢
      猜你喜欢
      • 2018-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-29
      相关资源
      最近更新 更多