以编程方式将UISearchBar添加到UITableView

时间:2011-08-04 20:04:23

标签: iphone uitableview interface uisearchbar

我正在尝试添加UISearchBar(及其相应的搜索逻辑),但是存在一个问题:我使用UITableViewController子类自动生成的UITableView而不是单独的{{ 1}}文件,并根据表视图以编程方式操作所有内容。

在Interface Builder中,可以选择将搜索栏搜索显示控制器添加到nib。有没有办法以编程方式完成相同的任务,或者是否有利于放弃默认的nib并转移到自定义UITableView nib文件,以便我可以轻松添加UITableView

此外,我已尝试通过我的UISearchbar实施中的以下代码测试我的UITableView标题(我希望它去的地方)添加搜索栏,但它出现了在表格部分标题后面,因此是不可见的,除非向下滚动表格以显示否则将是空白区域。怎么了?

viewDidLoad

4 个答案:

答案 0 :(得分:74)

要将UISearchBar添加到UITableView,可以执行以下操作:

  • 声明并初始化UISearchBar
  • 声明并初始化UISearchDisplayController
  • 将searchBar添加到tableView
  • 实施UISearchDisplayController委托
  • 在头文件中,我声明了我的searchBar,searchDisplayController以及包含要显示的数据的数组。

ViewController.h:

#import 

@interface ViewController : UITableViewController
{
    NSArray *originalData;
    NSMutableArray *searchData;

    UISearchBar *searchBar;
    UISearchDisplayController *searchDisplayController;
}

@end

我还在课堂上添加了两个代表: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;
}

现在我们需要初始化我们的两个对象,我评论了代码来解释我的工作:

//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重新加载自己。请参阅源代码以查看其他详细信息。

Download source file (Link UPDATED! (04.01.2016) )

答案 1 :(得分:21)

设置UISearchBar的框架:

// Change the position according to your requirements
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 70, 320, 44)];

如果您的观点是UITableViewController的子类,请将其更改为UIViewController

  • 在您的nib文件中,创建一个视图并在其下拖动tableView 查看并将该视图的引用类更改为您的 UIViewController

  • 创建IBOutlet UITableView * myTableView并将其连接到 你的nib文件。您只需将自己的VC文件更改为[self.myTableView reloadData];

现在您可以调整笔尖本身的tableView和搜索栏。

UISearchDisplay控制器有自己的UITableView,它显示搜索由另一个视图控制器管理的数据的结果。这里searchDisplaycontroller结合了搜索栏和tableview,以在tableview中显示结果数据,因此不需要单独的tableview。

答案 2 :(得分:2)

实施- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section。这将解决覆盖headerView

的Section Label问题

答案 3 :(得分:-1)

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

    }