2017-01-15 9 views
3

У меня есть два массива: FirstTableArray (включая название брендов) и SecondTableArray (включая модели).TableView search in Swift

Я хочу добавить поиск, по которому модель телефона может быть найдена по имени.

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 
    } 
} 

Помогите мне с этим?

ответ

26

Я работаю через то же самое сегодня и нашел этот учебник очень легко следовать: https://github.com/codepath/ios_guides/wiki/Search-Bar-Guide

Он будет считать вас через шаги добавления строки поиска в Interface Builder, настройки делегата и включения метода фильтрации результатов.

Предоставление пользователям возможности поиска по коллекции предметов является довольно распространенной задачей в проектах iOS. Стандартным интерфейсом для реализации поведения поиска является панель поиска.

Есть несколько распространенных способов работы с панелью поиска:

  • непосредственно с помощью UISearchBar. Это самый простой способ использовать UISearchBars. Это может быть чрезвычайно гибким, если вы хотите создать и запрограммировать свой собственный интерфейс поиска, однако не предоставляет множество встроенных функций, как и другие методы.

  • Использование UISearchDisplayController для управления интерфейсом поиска. UISearchDisplayController позволяет вам представить стандартный поиск со встроенными анимациями. Этот метод заставляет вас отображать результатов поиска в виде таблицы. - DEPRECATED

  • Использование UISearchController для управления интерфейсом поиска.
    UISearchController - это новый контроллер (доступен только в iOS 8+)
    , который поможет вам представить интерфейс поиска, используя любой вид, до
    Отобразить результаты поиска.

Данное руководство охватывает самые основы работы с каждым из этих классов. Ни один из этих классов не реализует «поиск» поведения поиска элементов, которые соответствуют заданной строке запроса, поскольку определение того, какие объекты соответствуют, будет отличаться в зависимости от конкретного случая использования домена (например, при поиске «людей», которые вы можете захотеть сопоставить только с их имена, тогда как вам может потребоваться полнотекстовый предварительно индексированный поиск при поиске по электронной почте). Вам придется выполнять любое поведение поиска/фильтрации самостоятельно.

Работа с UISearchBars непосредственно

По своей сути, панель поиска не более чем прославил текстовое поле упакованной с контролем области видимости и некоторые анимации и пару кнопок. На каждой панели поиска есть делегат, который дает вам возможность отвечать на действия пользователя. Наиболее важные методы делегата:

  • textDidChange - большую часть времени вы будете реагировать на это событие по обновление отображаемого набора результатов поиска, как пользователь печатает из запроса
  • searchBarSearchButtonClicked - в в некоторых случаях, если операция поиска медленна (например, требуется медленный вызов API), вы должны подождать , пока пользователь не закроет кнопку поиска до обновления результатов поиска .

Пример поиск таблицы

Начнет с одного приложением просмотра с основным UITableView. Вы можете добавить UISearchBar так же, как и с любым другим элементом управления, перетащив его в контроллер представления в построителе интерфейса или программно добавив его.

Свойство delegate панели поиска должно быть установлено в объект, реализующий UISearchBarDelegate. Как правило, вы создаете контроллер представления UISearchBarDelegate и устанавливаете метод searchBar.delegate = self в viewDidLoad.

enter image description here

Код для реализации поисковое поведение выглядит следующим образом. Мы сохраняем дополнительный массив filterData для представления строк данных, соответствующих нашему поисковому тексту. При изменении текста поиска мы обновляем filterData и перезагружаем нашу таблицу.

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() 
} 
} 

Вот как это выглядит при работе. Обратите внимание, что результаты поиска отображаются в одной таблице, и нет представления отдельного интерфейса поиска.

source: imgur.com

Пример поиска вид сбора

С момента UISearchBar довольно прост, его можно комбинировать с любым abitrary зрения, чтобы построить свой собственный интерфейс поиска. Вот что это могло бы выглядеть в паре с представлением коллекции.

enter image description here

Код для этого, по существу, такой же, как и в случае с видом таблицы.

Отменять из поиска и скрытия клавиатуры

После пользователь нажимает на панели поиска, то появится клавиатура, и вы заметите, что он не будет уходить, когда вы нажмете на X. Вы можете показать Отменить когда пользователь нажимает на панель поиска, а когда пользователь нажимает «Отмена», спрячьте клавиатуру.

Существует отличный способ поискаBarTextDidBeginEditing для UISearchBarDelegate, который вызывается, когда пользователь начинает редактировать текст поиска. Вы можете показать кнопку Отмена в этом методе:

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. Этот контроллер обрабатывает некоторые из логики и анимации, представляя вам отдельный интерфейс поиска, но при этом позволяет указать, как отображаются результаты поиска. не

Пример поиска в таблицу

Существует в настоящее время нет встроенного объекта в библиотеке объектов Interface Builder для UISearchController. Самый простой способ создать это - сделать это программно. Это также создает UISearchBar и устанавливает для него свойство searchBar контроллера поиска. Вы можете добавить эту панель поиска в свою иерархию представления программно.

Чтобы обновить результаты поиска, вам необходимо реализовать протокол UISearchResultsUpdating и установить свойство searchResultsUpdater контроллера поиска.

Вам не нужно реализовывать UISearchControllerDelegate, если вам не нужно подключаться к событиям вокруг презентации интерфейса поиска.

Вводя это вместе, код выглядит следующим образом. Обратите внимание, что мы должны прочитать текст поиска из строки поиска в updateSearchResultsForSearchController. Еще одна вещь, которую следует отметить, это то, что мы задаем для свойства definePresentationContext этого представления значение 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() 
    } 
} 
} 

Вот как это выглядит при работе. Обратите внимание, что в отличие от примера контроллера дисплея поиска, мы используем одно и то же представление таблицы для отображения результатов поиска вместо наложения отдельного вида таблицы. Однако, в отличие от работы с панелью поиска, мы все еще имеем встроенную анимацию при переходе на интерфейс поиска.

Кроме того, вы получаете логику, чтобы показать кнопку Отмена и скрыть клавиатуру, когда пользователь нажимает кнопку отмены бесплатно, когда вы используете это.

enter image description here

Пример поиск вида сбора

Мы можем так же легко использовать контроллер поиска для поиска вида сбора на месте. У нас все еще есть представление интерфейса поиска, но в отличие от работы с контроллером отображения поиска мы не ограничиваемся использованием табличного представления для отображения результатов поиска.

enter image description here

Код для этого является почти такой же, как при поиске на просмотр таблицы выше. Единственная заметная разница заключается в том, что нам пришлось представить представление-заполнитель в построителе интерфейса для панели поиска, так как есть еще некоторые причуды с размещением панели поиска контроллера поиска в дополнительном представлении коллекционного представления.

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 
    } 

    ... 
} 

Search Bar в навигации Посмотреть

общим требованием является размещение панели поиска внутри панели навигации.

enter image description here

Это может быть сконфигурирован в 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 
+0

В Swift 3+ протокол 'UISearchResultsUpdating' для обновления изменился подписи:' func updateSearchResults (для searchController: UISearchController) ' – Despotovic

1

Я хотел бы предложить implemeting в UISearchBar и добавить свой класс в качестве делегата на UISearchBar, а затем в методах делегатов вы можете взять текст SearchBar и выполнить поиск на datasouce, а затем перезагрузить данные Tableview соответственно

Edit: Вы можете использовать этот учебник о том, как реализовать UISearchBar на UITableView https://www.raywenderlich.com/113772/uisearchcontroller-tutorial

+0

Можете ли вы показать несколько примеров с кодом? Благодарю. – user6023982

+0

@John ссылка истек. но это должно быть комментарий –