web-dev-qa-db-ja.com

UITableViewでUISearchControllerを実装する方法-Swift

私はSwiftの初心者で、UITableViewクラスにあるUIViewControllerに検索機能を追加しようとしています。多くのことをグーグルで調べ、UISearchDisplayControllerが廃止され、UISearchControllerに置き換えられました。 UITableViewに特化していないチュートリアルを検索しようとしましたが、それらのいくつかはUITableViewControllerに実装するためのものでした。

  1. UISearchControllerクラスにあるUITableViewUIViewControllerを実装できますか? (できると思います)

  2. 可能であれば、Objective-Cで記述されたこれらのコード行を変換してください。または、本当に良いチュートリアルがあれば教えてください。

    @property (strong, nonatomic) UISearchController *searchController;
    
    UITableViewController *searchResultsController = [[UITableViewController alloc] init];
    
    // Init UISearchController with the search results controller
     self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsController];
    
    // Link the search controller
    self.searchController.searchResultsUpdater = self;
    

ソース

EDIT:検索結果アップデーターを次のように割り当てようとしています。

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchResultsUpdating {

    override func viewDidLoad() {

       super.viewDidLoad()
       self.view.backgroundColor = UIColor.blackColor() 
       self.addTableViewWithSection() 
       self.searchResultsController = UITableViewController()           
       var controller = UISearchController(searchResultsController: nil)            
       controller.searchResultsUpdater = self           
       controller.dimsBackgroundDuringPresentation = false   
    }
}

*ただし、controller.searchResultsUpdater = selfの行では、タイプ「 UISearchResultsUpdating ?」の値にtyp「ViewController」の値を割り当てることができないため、エラーが発生します。.. UISearchController UIViewController type classで使用できるかどうかは本当に疑わしい。

42
user4790024

はい、検索の仕組みは、私がより良いシステムだと考えるもののために根本的に変更されました。新しいシステムは、はるかに優れており、ほとんどの単純な実装のポイントにまっすぐです。使い方はとても簡単です。

まず、クラスをUISearchResultsUpdatingプロトコルに準拠させます。

class MyTableViewController: UITableViewController, UISearchResultsUpdating {}

検索コントローラープロパティに追加します。

class MyTableViewController: UTableViewController, UISearchResultsUpdating {
    let searchController = UISearchController(searchResultsController: nil)
}

ViewDidLoadに検索バーを追加します。

override func viewDidLoad() {
    super.viewDidLoad()

    searchController.searchResultsUpdater = self
    searchController.hidesNavigationBarDuringPresentation = false
    searchController.dimsBackgroundDuringPresentation = false
    searchController.searchBar.sizeToFit()
    self.tableView.tableHeaderView = searchController.searchBar
}

そして最後に、updateSearchResults:forUISearchResultsUpdatingプロトコルからのメソッド:

func updateSearchResults(for searchController: UISearchController) {

}

もちろん、このメソッドの実装は、データの検索元によって異なります。入力すると、現在のテーブルビューが検索内容で更新されます。必ずデータソースを更新し、updateSearchResultsForSearchControllerメソッドでテーブルビューをリロードしてください。繰り返しますが、入力すると更新されるため、検索するデータが大きい場合、またはインターネットから検索している場合は、このメソッドに並行性を追加してください。

別のコントローラーを使用して検索結果を取り込む場合は、searchControllerプロパティを初期化するときにVC)を渡すことができます。

[〜#〜] edit [〜#〜]:質問を読み直しましたが、重要なものを追加するのを忘れたようです。

UITableViewControllerには、tableViewというメンバーがあります。コントローラーのテーブルビューを取得できますが、UITableViewを設定するために、それに触れる必要はありません。 SearchControllerロジック)を直接とUITableViewで使用することはできません。そこに到達するためにコントローラーを操作する必要があります。 UITableViewControllerデリゲートメソッドとデータソースメソッドを使用して、検索結果でテーブルUIを更新します。

UITableViewController、UITableViewDelegate、およびUITableViewDataSourceを使用して読んで、検索結果を取得する方法を理解してください。

72
Andy Ibanez

私のように周りを驚かせている人の場合、このコードは役立つかもしれません

class ViewController: UIViewController , UITableViewDataSource, UITableViewDelegate,UISearchResultsUpdating {

    @IBOutlet weak var tblView: UITableView!

    var tabledata = ["lucques","chickendijon","godaddy","Amazon","chris","ambata","bankofamerica","abelcine","AUTO + TRANSPORTATION","BILLS + UTILITIES","FOOD + DINING","HEALTH","AutoCare", "Auto Payment" , "Gas+Fuel","Electric Bill", "Internet/Television","Fast Foodd", "Gorceries" , "Restaurants","Gym Membership", "Health Insurance","auto","note-bullet","knife","heart"]

    var filteredTableData = [String]()
    var resultSearchController = UISearchController()

    override func viewDidLoad() {
        super.viewDidLoad()
        tblView.delegate = self
        tblView.dataSource = self
        self.resultSearchController = ({
            let controller = UISearchController(searchResultsController: nil)
            controller.searchResultsUpdater = self
            controller.dimsBackgroundDuringPresentation = false
            controller.searchBar.sizeToFit()
            controller.searchBar.barStyle = UIBarStyle.Black
            controller.searchBar.barTintColor = UIColor.whiteColor()
            controller.searchBar.backgroundColor = UIColor.clearColor()
            self.tblView.tableHeaderView = controller.searchBar
            return controller
        })()
        self.tblView.reloadData()
    }

     func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if self.resultSearchController.active {
           return self.filteredTableData.count
        }else{
            return self.tabledata.count
       }
    }
     func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var section = indexPath.section
        var row = indexPath.row
        let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier:"addCategoryCell")
        cell.selectionStyle =  UITableViewCellSelectionStyle.None
        cell.backgroundColor = UIColor.clearColor()
        cell.contentView.backgroundColor = UIColor.clearColor()
        cell.textLabel?.textAlignment = NSTextAlignment.Left
        cell.textLabel?.textColor = UIColor.blackColor()
        cell.textLabel?.font = UIFont.systemFontOfSize(14.0)

        if self.resultSearchController.active {
              cell.textLabel?.text = filteredTableData[indexPath.row]
        } else {
                 cell.textLabel?.text = tabledata[indexPath.row]
        }
        return cell
    }

    func updateSearchResultsForSearchController(searchController: UISearchController) {
        filteredTableData.removeAll(keepCapacity: false)
        let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text)
        let array = (tabledata as NSArray).filteredArrayUsingPredicate(searchPredicate)
        filteredTableData = array as! [String]
        self.tblView.reloadData()

    }
}
23
user4790024

これを実装するすべての側面についてもう少しコンテキストを探している人のために、ここに ISearchControllerの実装方法に関するチュートリアル があります。

Andy Ibanezによる上記の回答 に加えて、UITableViewDataSourceメソッドにコードを追加して、新しくフィルター処理された結果をtableviewに表示する必要があります。

また、updateSearchResultsメソッドでtableView.reloadData()を呼び出すことを忘れないでください。UISearchControllerは、tableViewにそのデータを再ロードするように自動的に通知しません。

0
Bdebeez