UIVeController中的UISearchController

Unc*_*nzo 13 uitableview swift uisearchcontroller

我想在Swift中创建与Apple的地图应用程序类似的功能.无论如何将UISearchController集成到常规视图中(即:不是UITableView).在连接的搜索栏内单击后,通过Storyboard删除一个导致崩溃.或者有什么方法可以用UITableView实现这个结果?

ada*_*uet 37

如果你想将UISearchController与非UITableView一起使用,我就是这样做的.

由于UISearchControllerIB 支持(尚未!),因此您无需在其中添加任何内容,例如UISearchBar.

@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
Run Code Online (Sandbox Code Playgroud)

我希望它足够工作:-)

那么当然你至少需要实现UITableViewDelegate,UITableViewDataSource,UISearchResultsUpdater方法.

请享用!

  • 谢谢!这帮助我最终过渡到UISearchController!此外,您不必创建UITableView来显示项目.如果将searchResultsController设置为nil,它将在当前视图中查找任何TableView. (2认同)

Rob*_*hen 7

试图找出UISearchController自己.将它设置titleView为方便,但在我的一个页面上,我不得不把它放在searchBar靠近顶部的地方UIViewController:

// 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
}
Run Code Online (Sandbox Code Playgroud)

更新:

UISearchController在一两个项目中实施后,我发现自己倾向于@ adauguet将搜索栏嵌入导航栏的方法.

这是Swift中的代码.但有一个区别是它没有设置searchBar委托,因为searchResultsUpdater已经监听了文本更改.

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
}
Run Code Online (Sandbox Code Playgroud)

此外,我写了一篇博文,从头开始创建一个UISearchController用于显示地图搜索结果的项目.它还可以在地图项目中执行您可能需要的其他操作,例如获取用户位置,放置引脚,将地标解析为单行地址,以及创建标注按钮,将您带到Apple地图以获取行车路线.

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

博客帖子很长,所以如果您只想跳到代码,这里是相关的git repo:

https://github.com/ThornTechPublic/MapKitTutorial


Raj*_*tia 3

我在故事板的视图控制器中添加了搜索栏和搜索显示控制器。视图控制器仅包含搜索栏和搜索显示控制器,没有自己的 TableView。当您在视图控制器中添加搜索栏时,它会自动将您的视图控制器设置为其委托。

现在,搜索栏和搜索显示控制器本身有一个表格视图,当您在框内单击并开始键入时,它会使用该表格视图显示搜索结果。该表视图期望您的视图控制器提供 numberOfRowsInSection 和 cellForRowAtIndexPath 函数的实现,以便正确显示数据。

当您在没有这些的情况下运行项目并点击搜索栏内部时,您将收到以下错误:-

tableView:numberOfRowsInSection:]: 无法识别的选择器发送到实例 0x7fbf63449660 *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序

如果您看到,则错误出现在 numberOfRowsInSection 方法处。

更改您的视图控制器定义

class ViewController: UIViewController
Run Code Online (Sandbox Code Playgroud)

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource
Run Code Online (Sandbox Code Playgroud)

并实施所需的方法:-

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

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 0
}
Run Code Online (Sandbox Code Playgroud)

我刚刚在上述方法中添加了默认返回值。

现在,如果您在 searchviewdelegate 方法中过滤掉数据源,并在上述两种方法中正确设置行数和单元格信息,它应该可以工作。

希望这可以帮助!

  • 您是在谈论“UISearchDisplayController”吗?您一直说“搜索显示控制器”,但该类在 iOS 8 中已被弃用。 (2认同)
  • 答案是指“UISearchDisplayController”(在 iOS 8 中已弃用)。尽管实现上述答案中的方法对于结果表的委托来说仍然是必要的,但它们并不是 iOS 8 中新的“UISearchController”的完整图片。其余部分请参阅 adauguet 的答案。 (2认同)