iOS搜索功能 詳細教程
iOS實現搜索功能的類:
iOS 8.0-:UISearchBar + UISearchDisplayController(用于展示結果)
- 但是,iOS8.0棄用了UISearchDisplayController。
iOS 8.0+:UISearchController
- 使用UISearchController來非常方便的添加搜索框,UISearchController帶有SearchBar屬性,無需單獨創建。
區別:
UISearchDisplayController自帶展示結果的TableView, 使用UISearchDisplayController的時候,搜索結果的展示tableView系統已經幫我們封裝好;
但是,使用UISearchController,我們需要提供一個搜索結果的展示TableView.
Api
iOS8.0棄用了的UISearchDisplayController,就不介紹了。
主要介紹:
@interface UISearchController : UIViewController <UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning>
@protocol UISearchControllerDelegate <NSObject> //監控SearchController
@protocol UISearchResultsUpdating <NSObject> //響應輸入的搜索文本內容
@interface UISearchBar : UIView <UIBarPositioning, UITextInputTraits>
@protocol UISearchBarDelegate <UIBarPositioningDelegate>
//監控SearchBar上的行為:輸入&各個按鈕點擊
UISearchBar
先熟悉SearchBar的結構,它是一個UIView。所有api都圍繞著SearchBar上的控件進行定制:

@interface UISearchBar : UIView <UIBarPositioning, UITextInputTraits>
//創建
- (instancetype)init;
- (instancetype)initWithFrame:(CGRect)frame;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder;
//設置
//文字內容
@property(nullable,nonatomic,copy) NSString *text; // current/starting search text
@property(nullable,nonatomic,copy) NSString *prompt; // default is nil
@property(nullable,nonatomic,copy) NSString *placeholder; // default is nil
//樣式設置
@property(nonatomic) UIBarStyle barStyle; // default is UIBarStyleDefault (blue)
@property (nonatomic) UISearchBarStyle searchBarStyle; //searchBarStyle樣式
typedef enum UISearchBarStyle : NSUInteger {
UISearchBarStyleDefault,
UISearchBarStyleProminent,
UISearchBarStyleMinimal
} UISearchBarStyle;
@property(null_resettable, nonatomic,strong) UIColor *tintColor;
@property(nullable, nonatomic,strong) UIColor *barTintColor; // default is nil
@property(nonatomic,assign,getter=isTranslucent) BOOL translucent; //設置是否半透明
- (void)setBackgroundImage:(nullable UIImage *)backgroundImage forBarPosition:(UIBarPosition)barPosition barMetrics:(UIBarMetrics)barMetrics;
- (nullable UIImage *)backgroundImageForBarPosition:(UIBarPosition)barPosition barMetrics:(UIBarMetrics)barMetrics;
@property(nullable, nonatomic,strong) UIImage *backgroundImage;
- (void)setSearchFieldBackgroundImage:(nullable UIImage *)backgroundImage forState:(UIControlState)state;
- (nullable UIImage *)searchFieldBackgroundImageForState:(UIControlState)state;
@property(nonatomic) UIOffset searchFieldBackgroundPositionAdjustment;
@property(nonatomic) UIOffset searchTextPositionAdjustment;
//UISearchBarIcon(searchBar上的幾個按鈕)
typedef enum UISearchBarIcon : NSInteger {
UISearchBarIconSearch,
UISearchBarIconClear,
UISearchBarIconBookmark,
UISearchBarIconResultsList
} UISearchBarIcon;
//各個按鈕的圖標
- (void)setImage:(nullable UIImage *)iconImage forSearchBarIcon:(UISearchBarIcon)icon state:(UIControlState)state;
//各個按鈕的位置
- (nullable UIImage *)imageForSearchBarIcon:(UISearchBarIcon)icon state:(UIControlState)state;
// 按鈕的位置
- (void)setPositionAdjustment:(UIOffset)adjustment forSearchBarIcon:(UISearchBarIcon)icon;
- (UIOffset)positionAdjustmentForSearchBarIcon:(UISearchBarIcon)icon;
//Custom顯示
@property (nullable, nonatomic, readwrite, strong) UIView *inputAccessoryView;
@property (nonatomic, readonly, strong) UITextInputAssistantItem *inputAssistantItem NS_AVAILABLE_IOS(9_0) ; //Shown on top of the keyboard when search is engaged.
//Buttons
@property(nonatomic) BOOL showsBookmarkButton; // default is NO
@property(nonatomic) BOOL showsCancelButton; // default is NO
- (void)setShowsCancelButton:(BOOL)showsCancelButton animated:(BOOL)animated;
@property(nonatomic) BOOL showsSearchResultsButton; // default is NO
@property(nonatomic, getter=isSearchResultsButtonSelected) BOOL searchResultsButtonSelected; // default is NO
//ScopeBar
@property(nonatomic) BOOL showsScopeBar; // default is NO. if YES, shows the scope bar. call sizeToFit: to update frame
@property(nullable, nonatomic,copy) NSArray<NSString *> *scopeButtonTitles ; // array of NSStrings. no scope bar shown unless 2 or more items
@property(nonatomic) NSInteger selectedScopeButtonIndex; // index into array of scope button titles. default is 0. ignored if out of range
- (void)setScopeBarButtonBackgroundImage:(nullable UIImage *)backgroundImage forState:(UIControlState)state;
- (nullable UIImage *)scopeBarButtonBackgroundImageForState:(UIControlState)state;
@property(nullable, nonatomic,strong) UIImage *scopeBarBackgroundImage;
- (void)setScopeBarButtonDividerImage:(nullable UIImage *)dividerImage forLeftSegmentState:(UIControlState)leftState rightSegmentState:(UIControlState)rightState;
- (nullable UIImage *)scopeBarButtonDividerImageForLeftSegmentState:(UIControlState)leftState rightSegmentState:(UIControlState)rightState;
- (void)setScopeBarButtonTitleTextAttributes:(nullable NSDictionary<NSString *, id> *)attributes forState:(UIControlState)state;
- (nullable NSDictionary<NSString *, id> *)scopeBarButtonTitleTextAttributesForState:(UIControlState)state;
@property(nullable,nonatomic,weak) id<UISearchBarDelegate> delegate;
@end
UISearchBarDelegate
// FIXME: UISearchBarDelegate
// return NO to not become first responder
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar{
NSLog(@"%s",__func__);
return YES;
}
// called when text starts editing
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
NSLog(@"%s",__func__);
NSLog(@"searchBar.text = %@",searchBar.text);
}
// return NO to not resign first responder
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
NSLog(@"%s",__func__);
return YES;
}
// called when text ends editing
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
NSLog(@"%s",__func__);
NSLog(@"searchBar.text = %@",searchBar.text);
}
// called before text changes
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
NSLog(@"%s",__func__);
NSLog(@"searchBar.text = %@",searchBar.text);
return YES;
}
// called when text changes (including clear)
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSLog(@"%s",__func__);
NSLog(@"searchBar.text = %@",searchBar.text);
}
// called when keyboard search button pressed 鍵盤搜索按鈕
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
NSLog(@"%s",__func__);
NSLog(@"searchBar.text = %@",searchBar.text);
}
// called when bookmark button pressed
- (void)searchBarBookmarkButtonClicked:(UISearchBar *)searchBar{
NSLog(@"%s",__func__);
}
// called when cancel button pressed
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
NSLog(@"%s",__func__);
}
// called when search results button pressed
- (void)searchBarResultsListButtonClicked:(UISearchBar *)searchBar{
NSLog(@"%s",__func__);
}
// selecte ScopeButton
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope {
NSLog(@"%s",__func__);
NSLog(@"selectedScope = %ld",selectedScope);
}
UISearchController
@interface UISearchController : UIViewController <UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning>NS_CLASS_AVAILABLE_IOS(8_0)
//創建
- (instancetype)initWithSearchResultsController:(nullable UIViewController *)searchResultsController;
// Pass nil if you wish to display search results in the same view that you are searching.
// searchResultsController 用來顯示結果
//常用屬性
@property (nonatomic, strong, readonly) UISearchBar *searchBar;
@property (nullable, nonatomic, strong, readonly) UIViewController *searchResultsController;
@property (nonatomic, assign, getter = isActive) BOOL active;
//The presented state of the search interface. //顯示結果的意思
//This property to determine whether the search results are displayed.
//You can set this property to YES to force the search interface to appear, even if the user has not taps in the search field.
//The default value of this property is NO.
@property (nullable, nonatomic, weak) id <UISearchControllerDelegate> delegate;
@property (nullable, nonatomic, weak) id <UISearchResultsUpdating> searchResultsUpdater;
//顯示
@property (nonatomic, assign) BOOL dimsBackgroundDuringPresentation; //設置是否在搜索時顯示半透明背景
@property (nonatomic, assign) BOOL obscuresBackgroundDuringPresentation NS_AVAILABLE_IOS(9_1); //whether the underlying content is obscured during a search.
@property (nonatomic, assign) BOOL hidesNavigationBarDuringPresentation; //設置是否在搜索時隱藏導航欄
@end
UISearchResultsUpdating & UISearchControllerDelegate
#pragma mark UISearchResultsUpdating
// 每次更新搜索框里的文字,就會調用這個方法
// Called when the search bar's text or scope has changed or when the search bar becomes first responder.
// 根據輸入的關鍵詞及時響應:里面可以實現篩選邏輯 也顯示可以聯想詞
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSLog(@"%s",__func__);
// 獲取搜索框里地字符串
NSString *searchString = searchController.searchBar.text;
//一般在這里實現搜索的邏輯 & 展示搜索結果
}
#pragma mark UISearchControllerDelegate
// These methods are called when automatic presentation(展示結果) or dismissal(不展示結果) occurs.
// They will not be called if you present or dismiss the search controller yourself.
- (void)willPresentSearchController:(UISearchController *)searchController {
NSLog(@"%s",__func__);
}
- (void)didPresentSearchController:(UISearchController *)searchController{
NSLog(@"%s",__func__);
}
- (void)willDismissSearchController:(UISearchController *)searchController{
NSLog(@"%s",__func__);
}
- (void)didDismissSearchController:(UISearchController *)searchController{
NSLog(@"%s",__func__);
}
// Called after the search controller's search bar has agreed to begin editing or when 'active' is set to YES. If you choose not to present the controller yourself or do not implement this method, a default presentation is performed on your behalf.
- (void)presentSearchController:(UISearchController *)searchController {
NSLog(@"%s",__func__);
}
應用
實現搜索的方式:
- iOS 8.0和之前的版本:UISearchBar + UISearchDisplayController(這里就不詳細介紹了)
- iOS 8.0和以上的版本:UISearchController & UISearchBar
- UISearchController 當前頁面顯示搜索結果
- UISearchController 新控制器顯示搜索結果(比較常用)
- 單獨使用UISearchBar
Demo:https://github.com/CwLife/search_demo.git
UISearchController
黑技術
BUG:
使用UISearchController實現搜索功能時,當從搜索頁返回時,UISearchController的UISearchBar不消失!
原因:
UISearchController繼承自UIViewController,也就是說UISearchController自身也帶有一個View。但我們在使用UISearchController的時候并未將UISearchController自帶的View添加在self.view上,也就是未指定那個controller顯示UISearchController自帶View上的控件。
因此,UISearchController的searchBar不會跟隨搜索頁面移動而跟隨搜索頁的退出一起消失。
解決辦法:
UIViewController里有一個屬性:@property (nonatomic,assign)BOOL definesPresentationContext;
這一屬性決定了那個父控制器的View,將會以優先于UIModalPresentationCurrentContext這種呈現方式來展現自己的View。如果沒有父控制器設置這一屬性,那么展示的控制器將會是根視圖控制器。
只要在要實現搜索功能的控制器里設置:== self.definesPresentationContext = YES; == 即可實現UISearchController的UISearchBar跟隨搜索頁面一起滑動。一起消失。
self.definesPresentationContext = YES;
注意:
如果不設置:self.definesPresentationContext = YES;那么
如果設置了hidesNavigationBarDuringPresentation=YES,在進入編輯模式的時候會導致searchBar看不見(偏移-64)。
如果設置了hidesNavigationBarDuringPresentation=NO,在進入編輯模式會導致高度為64的空白區域出現(導航欄未渲染出來)。
如果設置:self.definesPresentationContext = YES;
如果設置了hidesNavigationBarDuringPresentation=YES,在進入編輯模式會正常顯示和使用。
如果設置了hidesNavigationBarDuringPresentation=NO,在進入編輯模式會導致搜索框向下偏移64.
關于搜索結果界面
關鍵:何時顯示結果界面?
當用戶開始編輯搜索框時,會觸發(void)updateSearchResultsForSearchController:(UISearchController *)searchController
代理方法。UISearchController就會觸發(void)willPresentSearchController:(UISearchController *)searchController
代理方法,自動開始展示搜索結果界面:
- 當前界面展示:會自動顯示當前頁面的View 來展示搜索結果
- 新控制器界面展示: 會自動顯示新控制器的view 來展示搜索結果
此時,UISearchController進入Presentation模式,active的值是YES。可用來做判斷是否正在搜索。
(1)當前頁內顯示結果
@interface TwoViewController ()<UITableViewDataSource,UITableViewDelegate,UISearchResultsUpdating,UISearchControllerDelegate,UISearchBarDelegate>
@property (nonatomic, strong) UITableView *tableView;
@property (strong,nonatomic) NSMutableArray *dataList; //原始數據
@property (nonatomic, strong) UISearchController * searchController;
@property (strong,nonatomic) NSMutableArray *searchList; //搜索結果
@end
@implementation TwoViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.automaticallyAdjustsScrollViewInsets = NO;
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, XYScreenW, XYScreenH - 64) style:UITableViewStylePlain];
_tableView.backgroundColor = [UIColor whiteColor];
_tableView.delegate = self;
_tableView.dataSource = self;
[self.view addSubview:_tableView];
//UISearchController
_searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
_searchController.searchResultsUpdater = self;
_searchController.delegate = self;
_searchController.searchBar.placeholder = @"placeholder";
_searchController.searchBar.showsCancelButton = YES;
_searchController.searchBar.frame = CGRectMake(0, 0, XYScreenW, 60);
self.tableView.tableHeaderView = _searchController.searchBar;
//解決:退出時搜索框依然存在的問題
self.definesPresentationContext = YES;
}
#pragma mark UISearchResultsUpdating
// 每次更新搜索框里的文字,就會調用這個方法
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSLog(@"%s",__func__);
// 獲取搜索框里地字符串
NSString *searchString = searchController.searchBar.text;
//搜索邏輯
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS %@",searchString];
if (self.searchList!= nil) {
//清除結果數據
[self.searchList removeAllObjects];
}
//搜索結果
self.searchList = [[_dataList filteredArrayUsingPredicate:predicate] mutableCopy];
//刷新表格 展示搜索結果
[self.tableView reloadData];
}
// MARK: 懶加載
- (NSMutableArray *) dataList {
if (_dataList == nil) {
_dataList = [NSMutableArray arrayWithCapacity:100];
for (NSInteger i=0; i<100; i++) {
[_dataList addObject:[NSString stringWithFormat:@"%ld-FlyElephant",(long)i]];
}
}
return _dataList;
}
- (NSMutableArray *) searchList {
if (_searchList == nil) {
_searchList = [NSMutableArray array];
}
return _searchList;
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (self.searchController.active) { //正在展示搜索結果
return [self.searchList count];
}else{
return [self.dataList count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *flag=@"cellFlag";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:flag];
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:flag];
}
if (self.searchController.active) {
[cell.textLabel setText:self.searchList[indexPath.row]];
}
else{
[cell.textLabel setText:self.dataList[indexPath.row]];
}
return cell;
}
(2)在新控制器顯示搜索結果
@interface ThreeViewController ()<UITableViewDataSource,UITableViewDelegate,UISearchResultsUpdating,UISearchControllerDelegate,UISearchBarDelegate>
@property (nonatomic, strong) UITableView *tableView;
@property (strong,nonatomic) NSMutableArray *dataSource; //原始數據
@property (nonatomic, strong) UISearchController *searchController;
@property (strong,nonatomic) NSMutableArray *searchResults; //搜索結果
@property (strong,nonatomic) ResultVC *resultVC; //搜索結果展示控制器
@end
- (void)viewDidLoad {
[super viewDidLoad];
self.automaticallyAdjustsScrollViewInsets = NO;
//tableView
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, XYScreenW, XYScreenH - 64) style:UITableViewStylePlain];
_tableView.backgroundColor = [UIColor whiteColor];
_tableView.delegate = self;
_tableView.dataSource = self;
[self.view addSubview:_tableView];
//UISearchController
//創建顯示搜索結果控制器
_resultVC = [[ResultVC alloc] init];
_searchController = [[UISearchController alloc] initWithSearchResultsController:_resultVC];
_searchController.searchResultsUpdater = self;
_searchController.delegate = self;
_searchController.searchBar.placeholder = @"placeholder";
_searchController.searchBar.showsCancelButton = YES;
_searchController.hidesNavigationBarDuringPresentation = YES; //搜索時隱藏導航欄
_searchController.searchBar.delegate = self;
_searchController.searchBar.frame = CGRectMake(0, 0, XYScreenW,60);
self.tableView.tableHeaderView = _searchController.searchBar;
//解決:退出時搜索框依然存在的問題
self.definesPresentationContext = YES;
}
#pragma mark - UITableViewDelegate, UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// 如果用戶正在搜索,則返回搜索結果的count,否則直接返回數據源數組的count;
if (self.searchController.active) {
return self.searchResults.count;
}else {
return self.dataSource.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kUITableViewCellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kUITableViewCellIdentifier];
}
// 如果用戶正在搜索,則返回搜索結果對應的數據,否則直接返回數據數組對應的數據;
if (self.searchController.active) {
cell.textLabel.text = _searchResults[indexPath.row];
}else {
cell.textLabel.text = _dataSource[indexPath.row];
}
return cell;
}
#pragma mark UISearchResultsUpdating
// 每次更新搜索框里的文字,就會調用這個方法
// Called when the search bar's text or scope has changed or when the search bar becomes first responder.
// 根據輸入的關鍵詞及時響應:里面可以實現篩選邏輯 也顯示可以聯想詞
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSLog(@"%s",__func__);
//會自動顯示新控制器的view 來展示搜索結果
//獲取搜索框里地字符串
NSString *searchString = searchController.searchBar.text;
// 謂詞
/**
1.BEGINSWITH : 搜索結果的字符串是以搜索框里的字符開頭的
2.ENDSWITH : 搜索結果的字符串是以搜索框里的字符結尾的
3.CONTAINS : 搜索結果的字符串包含搜索框里的字符
[c]不區分大小寫[d]不區分發音符號即沒有重音符號[cd]既不區分大小寫,也不區分發音符號。
*/
// 創建謂詞
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS [CD] %@", searchString];
// 如果搜索框里有文字,就按謂詞的匹配結果初始化結果數組,否則,就用字體列表數組初始化結果數組。
if (_searchResults != nil && searchString.length > 0) {
//清除搜索結果
[_searchResults removeAllObjects];
_searchResults = [NSMutableArray arrayWithArray:[_dataSource filteredArrayUsingPredicate:predicate]];
} else if (searchString.length == 0) {
_searchResults = [NSMutableArray arrayWithArray:_dataSource];
}
//顯示搜索結果
//在新控制器調用刷新頁面的方法
self.resultVC.results = _searchResults;
}
// MARK: 數據源
- (NSMutableArray *) dataSource {
if (_dataSource == nil) {
_dataSource = [NSMutableArray arrayWithArray:[UIFont familyNames]];
}
return _dataSource;
}
- (NSMutableArray *) searchResults {
if (_searchResults == nil) {
_searchResults = [NSMutableArray array];
}
return _searchResults;
}
//在新控制器里:
//在獲得搜索結果數據時,調用刷新頁面的方法
@property (nonatomic,strong) NSArray *results;
-(void)setResults:(NSArray *)results {
NSLog(@"%s",__FUNCTION__);
_results = results;
[self.tableView reloadData];
}
3.UISearchBar

也可以單獨使用UISearchBar來實現搜索功能,通過代理方法監控UISearchBar上的操作來決定如何顯示結果:
-(void)viewDidLoad {
[super viewDidLoad];
//一般不會單獨使用searchBar,都是結合UISearchController使用
_searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(30, 100, 350, 60)];
_searchBar.delegate = self;
_searchBar.placeholder = @"placeholder";
_searchBar.prompt = @"prompt";
//_searchBar.text = @"直接搜";
_searchBar.searchBarStyle = UISearchBarStyleDefault;
//各個按鈕的圖標
[_searchBar setImage:[UIImage imageNamed:@"test.jpg"] forSearchBarIcon:UISearchBarIconBookmark state:UIControlStateNormal];
//各個按鈕的位置
[_searchBar setPositionAdjustment:UIOffsetMake(0, 0) forSearchBarIcon:UISearchBarIconSearch];
_searchBar.showsBookmarkButton = YES;
_searchBar.showsCancelButton = YES;
_searchBar.showsSearchResultsButton = YES; //與BookmarkButton重疊
_searchBar.showsScopeBar = YES;
_searchBar.scopeButtonTitles = @[@"scope01",@"scope02",@"scope03"];
[self.view addSubview:_searchBar];
}
// FIXME: UISearchBarDelegate
// called when keyboard search button pressed 鍵盤搜索按鈕
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
NSLog(@"%s",__func__);
NSLog(@"searchBar.text = %@",searchBar.text);
//可以在這里實現跳轉新控制器
//通過searchBar.text 參數來請求搜索結果
}
// called when bookmark button pressed
- (void)searchBarBookmarkButtonClicked:(UISearchBar *)searchBar{
NSLog(@"%s",__func__);
}
// called when cancel button pressed
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
NSLog(@"%s",__func__);
}
// called when search results button pressed
- (void)searchBarResultsListButtonClicked:(UISearchBar *)searchBar{
NSLog(@"%s",__func__);
}
// selecte ScopeButton
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope {
NSLog(@"%s",__func__);
NSLog(@"selectedScope = %ld",selectedScope);
}
Demo:https://github.com/CwLife/search_demo.git
Demo:https://github.com/CwLife/search_demo.git