UISearchBar
(対応する検索ロジックを含む)を追加しようとしていますが、問題があります:別のUITableViewController
の代わりにUITableView
サブクラスの自動生成nib
を使用していますファイル、およびテーブルビューの観点からプログラムですべてを操作します。
Interface Builderには、Search BarおよびSearch Display Controllerをnib
に追加するオプションがあります。この同じタスクをプログラムで達成する方法はありますか、デフォルトのUITableView
を放棄してカスタムUITableView
nibファイルに転送して、UISearchbar
を簡単に追加できますか?
また、UITableView
実装の次のコードを使用して、viewDidLoad
ヘッダーに検索バーを追加するだけでテストを試みました(テーブルセクションの後ろに表示されます)ヘッダーであるため、テーブルを下にスクロールして空白以外の部分を表示しない限り表示されません。これはどうしたの?
UISearchBar *testbar = [[UISearchBar alloc] init];
[[self tableView] setTableHeaderView:testbar];
UISearchBarのフレームを設定します。
// Change the position according to your requirements
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 70, 320, 44)];
ビューがUITableViewController
のサブクラスである場合、UIViewController
に変更します。
Nibファイルで、ビューを作成し、そのビューの下にtableViewをドラッグし、そのビューの参照クラスをUIViewController
に変更します。
UITableView * myTableView
のIBOutlet
を作成し、nibファイルに接続します。 VCファイルでselfを[self.myTableView reloadData];
に変更するだけです。
これで、ペン先自体のtableView
と検索バーを調整できます。
UISearchDisplay
コントローラーには、別のView Controllerが管理するデータの検索結果を表示する独自のUITableView
があります。ここで、searchDisplaycontroller
は、検索バーとテーブルビューを組み合わせてテーブルビューに結果データを表示するため、別のテーブルビューを必要としません。
UISearchBarをUITableViewに追加するには、次のことが必要です。
ViewController.h:
#import
@interface ViewController : UITableViewController
{
NSArray *originalData;
NSMutableArray *searchData;
UISearchBar *searchBar;
UISearchDisplayController *searchDisplayController;
}
@end
また、クラスに2つのデリゲートを追加しました。UISearchBarDelegateとUISearchDisplayDelegateがありますが、searchBarは機能しません。
データの初期化:
//ViewController.m
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
NSArray *group1 = [[NSArray alloc] initWithObjects:@"Napoli", @"Juventus", @"Inter", @"Milan", @"Lazio", nil];
NSArray *group2 = [[NSArray alloc] initWithObjects:@"Real Madrid", @"Barcelona", @"Villareal", @"Valencia", @"Deportivo", nil];
NSArray *group3 = [[NSArray alloc] initWithObjects:@"Manchester City", @"Manchester United", @"Chelsea", @"Arsenal", @"Liverpool", nil];
originalData = [[NSArray alloc] initWithObjects:group1, group2, group3, nil];
searchData = [[NSMutableArray alloc] init];
}
return self;
}
次に、2つのオブジェクトを初期化する必要があります。コードをコメントして、何をするのかを説明します。
//ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
/*the search bar widht must be > 1, the height must be at least 44
(the real size of the search bar)*/
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
/*contents controller is the UITableViewController, this let you to reuse
the same TableViewController Delegate method used for the main table.*/
searchDisplayController.delegate = self;
searchDisplayController.searchResultsDataSource = self;
//set the delegate = self. Previously declared in ViewController.h
self.tableView.tableHeaderView = searchBar; //this line add the searchBar
//on the top of tableView.
}
TableViewセルの初期化に関する部分はスキップすることにしました。ダウンロード可能なソースコードで見つけることができます。 :)
TableViewの準備ができたら、UISearchDisplayControllerDelegateを実装します!
デリゲートには、検索のあらゆる側面を制御する多くのメソッドがありますが、最も重要なのは
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
このメソッドは、searchBarに新しい文字を挿入するたびに呼び出され、searchStringを取得して、テーブル要素を検索し、YESを返します。
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[searchData removeAllObjects];
/*before starting the search is necessary to remove all elements from the
array that will contain found items */
NSArray *group;
/* in this loop I search through every element (group) (see the code on top) in
the "originalData" array, if the string match, the element will be added in a
new array called newGroup. Then, if newGroup has 1 or more elements, it will be
added in the "searchData" array. shortly, I recreated the structure of the
original array "originalData". */
for(group in originalData) //take the n group (eg. group1, group2, group3)
//in the original data
{
NSMutableArray *newGroup = [[NSMutableArray alloc] init];
NSString *element;
for(element in group) //take the n element in the group
{ //(eg. @"Napoli, @"Milan" etc.)
NSRange range = [element rangeOfString:searchString
options:NSCaseInsensitiveSearch];
if (range.length > 0) { //if the substring match
[newGroup addObject:element]; //add the element to group
}
}
if ([newGroup count] > 0) {
[searchData addObject:newGroup];
}
[newGroup release];
}
return YES;
}
それで全部です!このメソッドは、すべての要素で全文検索を実行します。検索が終了すると、tableView自体がリロードされます。他の詳細を確認するには、ソースコードを参照してください。
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
を実装します。これにより、headerViewをカバーするセクションラベルの問題が解決されます。
swiftで:
let searchController = UISearchController(searchResultsController: nil)
let topConstraint = NSLayoutConstraint(item: searchController.searchBar, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 40)
let leftConstraint = NSLayoutConstraint(item: searchController.searchBar, attribute: NSLayoutAttribute.Left, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Left, multiplier: 1, constant: 0)
let rightConstraint = NSLayoutConstraint(item: searchController.searchBar, attribute: NSLayoutAttribute.Right, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Right, multiplier: 1, constant: 0)
let heightConstraint = NSLayoutConstraint(item: searchController.searchBar, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 44)
searchController.searchBar.translatesAutoresizingMaskIntoConstraints = false
searchController.searchBar.addConstraint(heightConstraint)
searchController.searchBar.placeholder = "Search Here"
searchController.searchResultsUpdater = self
searchController.searchBar.delegate = self
self.view.addSubview(searchController.searchBar)
self.view.addConstraints([topConstraint, leftConstraint, rightConstraint])
デリゲートを追加:
class ViewController: UIViewController, UISearchBarDelegate
テーブルビューをリロードするデリゲートメソッドを追加します。
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
//add your custome code here after search a string
tableView.reloadData()
}
func searchBarTextDidEndEditing(searchBar: UISearchBar) {
//add your custome code here after finishing search
tableView.reloadData()
}