Uitableview UIViewController中的UISearchController

Uitableview UIViewController中的UISearchController,uitableview,swift,uisearchcontroller,Uitableview,Swift,Uisearchcontroller,我希望在Swift中创建类似于苹果地图应用程序的功能。是否可以将UISearchController集成到常规视图(即:不是UITableView)中。在连接的搜索栏中单击后,通过故事板中的一个会导致崩溃。或者有没有什么方法可以让我用一个合适的视角来实现这个结果 我在情节提要的“我的视图控制器”中添加了搜索栏和搜索显示控制器。视图控制器仅包含搜索栏和搜索显示控制器,没有自己的TableView。在视图控制器中添加搜索栏时,它会自动将视图控制器设置为其代理 现在,搜索栏和搜索显示控制器本身有一个表

我希望在Swift中创建类似于苹果地图应用程序的功能。是否可以将UISearchController集成到常规视图(即:不是UITableView)中。在连接的搜索栏中单击后,通过故事板中的一个会导致崩溃。或者有没有什么方法可以让我用一个合适的视角来实现这个结果

我在情节提要的“我的视图控制器”中添加了搜索栏和搜索显示控制器。视图控制器仅包含搜索栏和搜索显示控制器,没有自己的TableView。在视图控制器中添加搜索栏时,它会自动将视图控制器设置为其代理

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

如果在没有这些选项的情况下运行项目并点击搜索栏内部,则会出现以下错误:-

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

如果您看到,错误在numberOfRowsInSection方法中

从更改视图控制器定义

class ViewController: UIViewController

并实施所需的方法,这些方法是:-

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

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 0
}
我刚刚在上述方法中添加了默认返回值

现在,如果您在searchviewdelegate方法中筛选出数据源,并在上述两个方法中正确设置行数和单元格信息,那么它应该可以工作


希望这有帮助

如果您想将UISearchController与非UITableView一起使用,下面是我的做法

由于IB(尚未!)支持
UISearchController
,因此您确实需要在其中添加任何内容,如
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
@interface UIViewControllerSubclass()
@属性(强,非原子)UISearchController*searchController;
@结束
@UIViewControllerSubclass的实现
-(无效)viewDidLoad
{        
[超级视图下载];
//从这里进行任何自定义初始化。。。
//创建UITableViewController以显示搜索结果,因为在本例中,实际的视图控制器不是UITableViewController的子类
UITableViewController*searchResultsController=[[UITableViewController alloc]init];
//使用搜索结果控制器初始化UISearchController
self.searchController=[[UISearchController alloc]initwithsearchresultscocontroller:searchResultsController];
//链接搜索控制器
self.searchController.searchResultsUpdater=self;
//这显然是必要的,因为搜索栏将包含在导航栏中

self.searchController.hidesNavigationBarDuringPresentation=否; //需要(?)设置在导航栏中放置搜索栏 self.searchController.searchBar.searchBarStyle=UISearchBarStyleMinimum; //这是您在导航栏中设置搜索栏的位置,而不是使用表视图的标题。。。 self.navigationItem.titleView=self.searchController.searchBar; //确保搜索结果控制器显示在当前视图控制器中 self.definesPresentationContext=是; //设置代理和其他内容 searchResultsController.tableView.dataSource=self; searchResultsController.tableView.delegate=self; self.searchController.delegate=self; self.searchController.dimsBackgroundDuringPresentation=否; self.searchController.searchBar.delegate=self; } @结束
我希望这足以奏效:-)

当然,您至少需要实现UITableViewDelegate、UITableViewDataSource和UISearchResultsUpdater方法


享受吧

试图弄清楚我自己。将其设置为
标题视图
很方便,但在我的一个页面上,我不得不将
搜索栏
放在
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
}

更新:

在一两个项目中实现了
UISearchController
之后,我发现自己被@adauguet将搜索栏嵌入导航栏的方法所吸引

这是Swift的代码。不过,一个区别是它没有设置searchBar委托,因为
SearchResultsUpdate
已经侦听文本更改

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
显示地图搜索结果。它还可以在地图项目中执行其他您可能需要的操作,例如获取用户位置、放置PIN、将placemarks解析为单行地址,以及创建标注按钮,将您带到Apple Maps以获取驾驶方向

这篇博文很长,如果您只想跳到代码,下面是相关的git repo:


我在将UIViewController中的SearchDisplayController转换为ViewController中的SearchController时遇到了一些问题,因为SearchController的实现并不那么直观。但您只需将SearchController本身的searcher添加到任何视图中即可。但您不能设置约束,因为当您聚焦/选择它时,搜索栏会向上移动(如果您知道如何将约束添加到任何视图后将其设置为seachController.searchbar,请告诉我!)。下面我分享一份清单,我发现在ViewController中实现SearchController时,该清单非常重要/有价值

//您可以将searcher添加到任何视图中。它会自动向上移动,像魔术一样显示tableView。但由于这个原因,您不能将搜索栏的约束设置为要将其添加到的占位符视图

[self.searchBarPlaceHolderView addSubview:self.searchController.searchBar];
//您需要这样做,以防止在聚焦/选择时搜索栏下拉
[self.searchBarPlaceHolderView addSubview:self.searchController.searchBar];
self.searchController.hidesNavigationBarDuringPresentation = YES;
self.extendedLayoutIncludesOpaqueBars = true;
self.definesPresentationContext = YES;
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];