web-dev-qa-db-ja.com

SwiftのTableView検索

FirstTableArray(ブランド名を含む)とSecondTableArray(モデルを含む)の2つの配列があります。

電話のモデルを名前の一部で見つけることができる検索を追加したい。

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

これで私を助けてもらえますか?

9
user6023982

私は今日同じことをやっていますが、このチュートリアルは非常に簡単であることがわかりました: https://github.com/codepath/ios_guides/wiki/Search-Bar-Guide

Interface Builderに検索バーを追加し、デリゲートを設定し、結果をフィルタリングするメソッドを含める手順を説明します。


ユーザーがアイテムのコレクションを検索する方法を提供することは、iOSプロジェクトではかなり一般的なタスクです。検索動作を実装するための標準インターフェイスは、検索バーです。

検索バーを使用する一般的な方法はいくつかあります。

  • UISearchBarを直接使用します。これは、UISearchBarsを使用する最も基本的な方法です。独自の検索インターフェイスを設計およびプログラミングする場合、これは非常に柔軟になりますが、他の方法ほど多くの組み込み機能を提供しません。

  • UISearchDisplayControllerを使用して、検索インターフェイスの管理を支援します。 UISearchDisplayControllerを使用すると、組み込みのアニメーションで標準の検索インターフェイスを表示できます。このメソッドは、テーブルビューで検索結果を表示することを強制します。 -非推奨

  • UISearchControllerを使用して、検索インターフェイスの管理を支援します。の
    UISearchControllerは新しいコントローラーです(iOS 8以降でのみ使用可能)
    これは、あらゆる種類のビューを使用して検索インターフェイスを表示するのに役立ちます
    検索結果を表示します。

このガイドでは、これらの各クラスを操作する基本について説明します。これらのクラスは、特定のクエリ文字列に一致するアイテムを検索する「検索」動作を実際には実装していません。どのオブジェクトが一致するかはドメイン固有のユースケースによって異なるためです(たとえば、「電子メールで検索する場合は、フルテキストの事前インデックス検索が必要になる場合があります)。検索/フィルタリング動作を自分で実装する必要があります。

ISearchBarsを直接操作する

本質的に、検索バーは、スコープコントロールといくつかのアニメーションといくつかのボタンがパッケージ化された栄光のテキストフィールドにすぎません。各検索バーには、ユーザーアクションに応答する機会を与えるデリゲートがあります。最も重要なデリゲートメソッドは次のとおりです。

  • textDidChange-ほとんどの場合、ユーザーがクエリを入力しているときに表示される検索結果のセットを更新することにより、このイベントに応答します
  • searchBarSearchButtonClicked-場合によっては、検索操作が遅い場合(たとえば、遅いAPI呼び出しを行う必要がある場合)、ユーザーが検索結果を更新する前に検索ボタンをタップするまで待機することができます。

テーブルの検索例

基本的なUITableViewを持つ単一のビューアプリケーションから始めます。インターフェイスビルダーでビューコントローラーにドラッグするか、プログラムで追加することにより、他のコントロールと同様にUISearchBarを追加できます。

検索バーのデリゲートプロパティは、UISearchBarDelegateを実装するオブジェクトに設定する必要があります。通常、View ControllerにUISearchBarDelegateを実装させ、viewDidLoadメソッドでsearchBar.delegate = selfを設定します。

enter image description here

検索動作を実装するコードは次のとおりです。検索テキストに一致するデータの行を表すために、filteredDataの追加の配列を維持します。検索テキストが変更されると、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()
}
}

実行すると、次のようになります。検索結果は同じテーブルに表示され、別の検索インターフェイスは表示されないことに注意してください。

source: imgur.com

コレクションビューの検索例

UISearchBarは非常にシンプルなので、任意のビューと組み合わせて独自の検索インターフェイスを構築できます。コレクションビューと組み合わせた場合の外観は次のとおりです。

enter image description here

このコードは、テーブルビューの場合と基本的に同じです。

検索のキャンセルとキーボードの非表示

ユーザーが検索バーをタップすると、キーボードが表示され、Xをタップしても消えないことがわかります。ユーザーが検索バーをタップするとキャンセルボタンを表示でき、ユーザーがキャンセルをタップすると非表示になります。キーボード。

UISearchBarDelegateには、ユーザーが検索テキストの編集を開始したときに呼び出される気の利いたsearchBarTextDidBeginEditingメソッドがあります。そのメソッドで[キャンセル]ボタンを表示できます。

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

ユーザーがキャンセルボタンをタップすると、デリゲートのsearchBarCancelButtonClickedメソッドが呼び出されます。この時点で、[キャンセル]ボタンを非表示にし、検索バーの既存のテキストをクリアして、キーボードを次のように非表示にすることができます。

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

ISearchControllersを使用する(iOS 8以降)

検索インターフェイス(iOS 8以降でのみ使用可能)の表示を管理する新しい方法は、UISearchControllerを使用することです。このコントローラーは、検索結果の表示方法を指定しながら、個別の検索インターフェイスを表示するロジックとアニメーションの一部を処理します。

テーブルの検索例

現在、UISearchControllerのInterface Builder Object Libraryには組み込みオブジェクトはありません。作成する最も簡単な方法は、プログラムで作成することです。これにより、UISearchBarも作成され、検索コントローラーのsearchBarプロパティが設定されます。この検索バーは、プログラムでビュー階層に追加できます。

検索結果を更新するには、UISearchResultsUpdatingプロトコルを実装し、検索コントローラーのsearchResultsUpdaterプロパティを設定する必要があります。

検索インターフェイスの表示に関するイベントにフックする必要がない限り、UISearchControllerDelegateを実装する必要はありません。

すべてをまとめると、コードは次のようになります。 updateSearchResultsForSearchControllerの検索バーから検索テキストを読み取る必要があることに注意してください。他に注意すべきことは、このView ControllerのdefinePresentationContextプロパティをtrueに設定することです。これは、検索インターフェイスが表示されるときに、検索コントローラーがこのView Controllerのフレームを使用することを意味します(ルートView Controllerとは反対)。この場合、検索インターフェイスがキャリアバーの上に展開されることを意味します。

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
    }

    ...
}

ナビゲーションビューの検索バー

一般的な要件は、ナビゲーションバー内に検索バーを配置することです。

enter image description here

これは、View Controllerの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
52
Gibraltar

UISearchBarを実装し、クラスをUISearchBarへのデリゲートとして追加することをお勧めします。デリゲートメソッドでは、searchbarテキストを取得し、datasouceで検索を実行し、それに応じてtableviewデータを再読み込みします。

編集:UITableViewにUISearchBarを実装する方法については、このチュートリアルを使用できます https://www.raywenderlich.com/472-uisearchcontroller-tutorial-getting-started

1
John