Те из вас, кто использует UISearchController
в iOS 8 и более поздних версиях, могут просто создать подкласс UISearchController
. Для полноты вы также можете скрыть кнопку отменить, как это сделал я, поскольку удаление текста из UISearchBar
фактически означает отмену поиска. Я добавил этот код ниже, если вы хотите его использовать.
Преимущество этого состоит в том, что вы сможете использовать это для любого класса и любого представления, вместо того, чтобы требовать подкласс UIViewController
. Я даже укажу, как я инициализирую свой UISearchController
в конце этого решения.
FJSearchBar
Этот класс нужно переопределить только в том случае, если вы хотите скрыть кнопку отмены, как это сделал я. Маркировка searchController.searchBar.showsCancelButton = NO
, похоже, не работает в iOS 8. Я не тестировал iOS 9.
FJSearchBar.h
Пусто, но помещено здесь для полноты картины.
@import UIKit;
@interface FJSearchBar : UISearchBar
@end
FJSearchBar.m
#import "FJSearchBar.h"
@implementation FJSearchBar
- (void)setShowsCancelButton:(BOOL)showsCancelButton {
// do nothing
}
- (void)setShowsCancelButton:(BOOL)showsCancelButton animated:(BOOL)animated {
// do nothing
}
@end
FJSearchController
Вот где вы хотите внести настоящие изменения. Я разделил UISearchBarDelegate
на отдельную категорию, потому что, IMHO, категории делают классы чище и проще в обслуживании. Если вы хотите сохранить делегата в интерфейсе / реализации основного класса, вы можете это сделать.
FJSearchController.h
@import UIKit;
@interface FJSearchController : UISearchController
@end
@interface FJSearchController (UISearchBarDelegate) <UISearchBarDelegate>
@end
FJSearchController.m
#import "FJSearchController.h"
#import "FJSearchBar.h"
@implementation FJSearchController {
@private
FJSearchBar *_searchBar;
BOOL _clearedOutside;
}
- (UISearchBar *)searchBar {
if (_searchBar == nil) {
// if you're not hiding the cancel button, simply uncomment the line below and delete the FJSearchBar alloc/init
// _searchBar = [[UISearchBar alloc] init];
_searchBar = [[FJSearchBar alloc] init];
_searchBar.delegate = self;
}
return _searchBar;
}
@end
@implementation FJSearchController (UISearchBarDelegate)
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
// if we cleared from outside then we should not allow any new editing
BOOL shouldAllowEditing = !_clearedOutside;
_clearedOutside = NO;
return shouldAllowEditing;
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
// hide the keyboard since the user will no longer add any more input
[searchBar resignFirstResponder];
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if (![searchBar isFirstResponder]) {
// the user cleared the search while not in typing mode, so we should deactivate searching
self.active = NO;
_clearedOutside = YES;
return;
}
// update the search results
[self.searchResultsUpdater updateSearchResultsForSearchController:self];
}
@end
Некоторые детали, на которые следует обратить внимание:
- I've put the search bar and the
BOOL
as private variables instead of properties because
- They're more lightweight than private properties.
- Внешний мир не должен их видеть или изменять.
- Мы проверяем, является ли
searchBar
первым респондентом. Если это не так, мы фактически деактивируем контроллер поиска, потому что текст пуст, и мы больше не ищем. Если вы действительно хотите быть уверенным, вы также можете убедиться, что searchText.length == 0
.
searchBar:textDidChange:
вызывается перед searchBarShouldBeginEditing:
, поэтому мы обработали его в таком порядке.
- Я обновляю результаты поиска каждый раз, когда изменяется текст, но вы можете переместить
[self.searchResultsUpdater updateSearchResultsForSearchController:self];
на searchBarSearchButtonClicked:
, если хотите, чтобы поиск выполнялся только после того, как пользователь нажмет кнопку Search.
person
mikeho
schedule
06.03.2016