web-dev-qa-db-ja.com

UIViewControllerのUISearchController

SwiftでAppleのマップアプリケーションと同様の機能を作成したいと思っています。 UISearchControllerを通常のビューに統合する方法はありますか(つまり、UITableViewではありません)。ストーリーボードからドロップインすると、接続されている検索バーの内側をクリックするとクラッシュします。または、UITableViewを使用してこの結果を達成する方法はありますか?

13
UncleAlfonzo

ストーリーボードのビューコントローラーに検索バーと検索ディスプレイコントローラーを追加しました。ビューコントローラーには、検索バーと検索表示コントローラーのみが含まれ、独自のTableViewはありません。ビューコントローラに検索バーを追加すると、ビューコントローラが自動的にデリゲートとして設定されます。

これで、検索バーと検索表示コントローラーには、ボックス内をクリックして入力を開始したときに検索結果を表示するために使用する、それ自体のテーブルビューがあります。このテーブルビューは、ビューコントローラがデータを適切に表示するためのnumberOfRowsInSection関数とcellForRowAtIndexPath関数の実装を提供することを期待しています。

これらを使用せずにプロジェクトを実行し、検索バー内をタップすると、次のエラーが発生します。-

tableView:numberOfRowsInSection:]:認識されないセレクターがインスタンス0x7fbf63449660に送信されました***キャッチされなかった例外 'NSInvalidArgumentException'が原因でアプリを終了しています

表示されている場合、エラーはnumberOfRowsInSectionメソッドにあります。

ビューコントローラの定義をから変更します

class ViewController: UIViewController

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource

次のような必要なメソッドを実装します。-

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    return UITableViewCell()
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 0
}

上記のメソッドにデフォルトの戻り値を追加しました。

ここで、searchviewdelegateメソッドでデータソースを除外し、上記の2つのメソッドで行数とセル情報を適切に設定すると、機能するはずです。

お役に立てれば!

3
Rajeev Bhatia

UITableView以外でUISearchControllerを使用する場合は、次のようにしました。

UISearchControllerは(まだ!)IBでサポートされていないため、notUISearchBarのように何かを追加する必要があります。

@interface UIViewControllerSubclass () <UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UISearchControllerDelegate, UISearchResultsUpdating>

@property (strong, nonatomic) UISearchController *searchController;

@end

@implementation UIViewControllerSubclass

- (void)viewDidLoad
{        
    [super viewDidLoad];
    // Do any custom init from here...

    // Create a UITableViewController to present search results since the actual view controller is not a subclass of UITableViewController in this case
    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;

    // This is obviously needed because the search bar will be contained in the navigation bar
    self.searchController.hidesNavigationBarDuringPresentation = NO;

    // Required (?) to set place a search bar in a navigation bar
    self.searchController.searchBar.searchBarStyle = UISearchBarStyleMinimal;

    // This is where you set the search bar in the navigation bar, instead of using table view's header ...
    self.navigationItem.titleView = self.searchController.searchBar;

    // To ensure search results controller is presented in the current view controller
    self.definesPresentationContext = YES;

    // Setting delegates and other stuff
    searchResultsController.tableView.dataSource = self;
    searchResultsController.tableView.delegate = self;
    self.searchController.delegate = self;
    self.searchController.dimsBackgroundDuringPresentation = NO;
    self.searchController.searchBar.delegate = self;        
}

@end

私はそれが働くのに十分であることを願っています:-)

そしてもちろん、少なくともUITableViewDelegate、UITableViewDataSource、UISearchResultsUpdaterメソッドを実装する必要があります。

楽しい!

37
adauguet

UISearchControllerを自分で理解しようとしています。 titleViewに設定すると便利ですが、私のページの1つで、searchBarUIViewControllerの上部近くに配置する必要がありました。

// Add a normal View into the Storyboard.
// Set constraints:
// - height: 44
// - leading and trailing so that it spans the width of the page
// - vertical position can be anywhere based on your requirements, like near the top
@IBOutlet weak var searchContainerView: UIView!

var searchResultsController = UISearchController()

override func viewDidLoad() {
    // TODO: set the searchResultsController to something
    let controller = UISearchController(searchResultsController: nil)
    // have the search bar span the width of the screen
    controller.searchBar.sizeToFit()
    // add search bar to empty View
    searchContainerView.addSubview(controller.searchBar)
    searchResultsController = controller
}

更新:

1つか2つのプロジェクトでUISearchControllerを実装した後、検索バーをナビゲーションバーに埋め込むという@adauguetのアプローチに引力を感じました。

これがSwiftのコードです。ただし、1つの違いは、searchResultsUpdaterがすでにテキストの変更をリッスンしているため、searchBarデリゲートが設定されないことです。

override func viewDidLoad() {
    super.viewDidLoad()
//        locationManager.delegate = self
//        locationManager.desiredAccuracy = kCLLocationAccuracyBest
//        locationManager.requestWhenInUseAuthorization()
//        locationManager.requestLocation()
    let locationSearchTable = storyboard!.instantiateViewControllerWithIdentifier("LocationSearchTable") as! LocationSearchTable
    resultSearchController = UISearchController(searchResultsController: locationSearchTable)
    resultSearchController?.searchResultsUpdater = locationSearchTable
    let searchBar = resultSearchController!.searchBar
    searchBar.sizeToFit()
    searchBar.placeholder = "Search for places"
    navigationItem.titleView = resultSearchController?.searchBar
    resultSearchController?.hidesNavigationBarDuringPresentation = false
    resultSearchController?.dimsBackgroundDuringPresentation = true
    definesPresentationContext = true
}

また、UISearchControllerを使用して地図の検索結果を表示するプロジェクトを最初から作成するブログ投稿を作成しました。また、ユーザーの場所を取得したり、ピンをドロップしたり、目印を1行の住所に解析したり、Apple道順の地図。

http://www.thorntech.com/2016/01/how-to-search-for-location-using-apples-mapkit/

ブログ投稿は非常に長いので、コードにスキップしたい場合は、関連するgitリポジトリを次に示します。

https://github.com/ThornTechPublic/MapKitTutorial

8
Robert Chen

SearchControllerの実装はそれほど直感的ではないため、UIViewControllerのSearchDisplayControllerからViewControllerのSearchControllerへの変換に問題がありました。ただし、SearchController自体から任意のビューにサーチャーを追加するだけです。ただし、フォーカス/選択すると検索バーが上に移動するため、制約を設定することはできません(ビューに制約を追加した後、seachController.searchbarに制約を設定する方法を知っている場合は、お知らせください!)。以下に、ViewControllerにSearchControllerを実装するときに非常に重要/価値があると思ったチェックリストを共有します。

//任意のビューにサーチャーを追加できます。それは自動的に上に移動して、魔法のようにtableViewを表示します。ただし、このため、追加先のプレースホルダービューの検索バーに制約を設定することはできません。

[self.searchBarPlaceHolderView addSubview:self.searchController.searchBar];

//フォーカス/選択したときに検索バーがドロップダウンしないようにするためにこれが必要です。ナビゲーションバーのタイトルビューにsearchBarを追加する場合は、これをNOに設定することをお勧めします。

self.searchController.hidesNavigationBarDuringPresentation = YES;

//これをviewControllerで設定してください

self.extendedLayoutIncludesOpaqueBars = true;
self.definesPresentationContext = YES;

//検索コントローラーに表示可能なtableViewControllerも指定する必要があります。ジェネリックなものに対しては、self.searchResultsController = [[UITableView alloc] init]だけを実行することもできます。

self.searchResultsController = (UITableViewController *)[ [UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"searchResultsTableViewController"];

self.searchResultsController.tableView.dataSource = self;
self.searchResultsController.tableView.delegate = self;
self.searchResultsController.definesPresentationContext = NO;
self.searchController = [[UISearchController alloc] initWithSearchResultsController:self.searchResultsController];
0
coolcool1994