2014-10-17 5 views
12

Я ищу, чтобы создать аналогичную функциональность для приложений карт Apple в Swift. В любом случае необходимо интегрировать UISearchController в обычное представление (т. Е .: не UITableView). Сбрасывание одного из них через Storyboard приводит к сбою после нажатия внутри подключенной панели поиска. Или я могу достичь этого результата с помощью UITableView?UISearchController в UIViewController

ответ

2

Я добавил панель поиска и контроллер отображения в моем диспетчере просмотра в раскадровке. Контроллер представления содержит только панель поиска и контроллер отображения поиска и не имеет собственного TableView. Когда вы добавляете панель поиска в свой контроллер просмотра, он автоматически устанавливает ваш контроллер представления, поскольку он является делегатом.

Теперь панель поиска и поисковый контроллер дисплея имеют представление таблицы, которое оно использует для отображения результатов поиска, когда вы нажимаете внутри поля и начинаете вводить текст. В этом представлении таблицы ваш контроллер представления должен обеспечить реализацию функций numberOfRowsInSection и cellForRowAtIndexPath, чтобы он отображал данные правильно.

При запуске проекта без них и нажмите внутри панели поиска, вы получите следующее сообщение об ошибке: -

Tableview: numberOfRowsInSection]: непризнанные селектор направлен например 0x7fbf63449660 *** Нагрузочный приложение из-за uncaught exception '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 и правильно настроите количество строк и информацию о ячейке в вышеуказанных двух методах, оно должно работать.

Надеюсь, это поможет!

+0

Большое спасибо Rajeev! Это работало как шарм. Через неделю я стукнулся головой об этом, и я продвигаюсь вперед. Я понятия не имел, что SearchController имеет собственный встроенный табличный вид - это довольно аккуратно! – UncleAlfonzo

+0

Рад помочь и поблагодарить вас за принятие в качестве ответа. Я также был бы признателен, если бы вы были добрыми! –

+0

Но получить 15 репутации :(Я постараюсь изо всех сил помнить, когда я это сделаю, и вернусь сюда и подниму вас.Еще раз спасибо :) – UncleAlfonzo

36

Если вы хотите использовать UISearchController с не UITableView, вот как я это сделал.

Поскольку UISearchController (пока!) При поддержке IB, вы не нужно добавить что-нибудь в этом, как 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 

Я надеюсь, что это достаточно, чтобы работать :-)

Тогда, конечно, вы должны по крайней мере, для реализации методов UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdater.

Наслаждайтесь!

+2

Спасибо! Это помогло мне, наконец, перейти на UISearchController! Кроме того, вы не обязательно создаете UITableView для отображения элементов. Если вы установите для параметра searchResultsController значение nil, он будет искать любой TableView в текущем представлении. – DookieMan

+1

Спасибо. Я хотел бы уточнить для тех, у кого есть аналогичная проблема для моего, где UISearchBar исчезнет как часть представления заголовка табличного представления UIViewController (не UITableViewController). Ключевой линией была 'self.definesPresentationContext = true' (Swift). Это исправило это. –

+0

Это хорошее решение, но как перезагрузить таблицу? – kamyFC

6

Попытка выяснить, 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 
} 

UPDATE:

После реализации 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 
} 

Кроме того, я написал сообщение в блоге, что создает проект с нуля, который использует UISearchController для отображения результатов поиска на карте. Он также выполняет другие действия, которые вы можете захотеть в проекте карты, например, получить местоположение пользователя, вытащить булавки, разложить метки в однострочный адрес и создать кнопки выносок, которые доставят вас в Apple Maps для проезда.

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

Сообщение в блоге довольно долго, так вот, связанный мерзавец репо, если вы просто хотите, чтобы перейти к коду:

https://github.com/ThornTechPublic/MapKitTutorial

+0

Действительно полезно для меня! – Dasoga

+0

Эта структура пользовательского интерфейса была именно тем, что я искал. Спасибо, что поделился! –

+0

hidesNavigationBarDuringPresentation = v. важно! –

0

У меня были некоторые проблемы преобразования из SearchDisplayController в UIViewController для SearchController в ViewController, потому что реализация SearchController не такая интуитивная. Но вы можете просто добавить поисковика из самого SearchController в любое представление. Вы не можете установить ограничение, потому что панель поиска будет двигаться вверх, когда вы фокусируете/выбираете ее (если вы знаете, как установить ограничение для seachController.searchbar после добавления его в любое представление, LET ME KNOW!). Ниже я использую контрольный список, который я нашел очень важным/ценным при реализации SearchController в ViewController.

// вы можете просто добавить поисковика в любое представление. Он автоматически переместится вверх, чтобы показать tableView как магия. Но по этой причине вы не можете установить ограничение на панель поиска на представление замещающего, к которому вы добавляете.

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

// это необходимо для предотвращения выпадания строки поиска при ее фокусировке/выборе. Вы хотите установить это значение НЕТ, если вы добавляете searchBar в заголовок навигационной панели.

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];