1414#import " QMUIEmptyView.h"
1515#import " UISearchBar+QMUI.h"
1616#import " UITableView+QMUI.h"
17+ #import " NSString+QMUI.h"
18+ #import " NSObject+QMUI.h"
19+ #import " UIView+QMUI.h"
1720
1821BeginIgnoreDeprecatedWarning
1922
@@ -41,28 +44,136 @@ - (void)initTableView {
4144
4245@end
4346
44- @interface QMUISearchController ()<UISearchResultsUpdating,UISearchControllerDelegate,QMUISearchResultsTableViewControllerDelegate,UISearchDisplayDelegate>
47+ @interface QMUISearchDisplayController : UISearchDisplayController
4548
46- // iOS8及以后使用这个
47- @property (nonatomic ,strong ) UISearchController *searchController;
49+ @property (nonatomic , strong ) UIView *customDimmingView;
50+ @property (nonatomic , copy ) void (^dimmingViewVisibleChangedBlock)(BOOL visible);
51+ @end
52+
53+ @implementation QMUISearchDisplayController
54+
55+ - (void )setActive : (BOOL )visible animated : (BOOL )animated {
56+ [super setActive: visible animated: animated];
57+ if (self.customDimmingView .superview ) {
58+ BOOL shouldChangeSize = !CGSizeEqualToSize (self.customDimmingView .frame .size , self.customDimmingView .superview .bounds .size );
59+ [UIView qmui_animateWithAnimated: animated duration: [CATransaction animationDuration ] animations: ^{
60+ self.customDimmingView .superview .alpha = visible ? 1 : 0 ;
61+ if (shouldChangeSize) {
62+ self.customDimmingView .frame = self.customDimmingView .superview .bounds ;
63+ }
64+ }];
65+ }
66+ }
67+
68+ - (void )setCustomDimmingView : (UIView *)customDimmingView {
69+ if (_customDimmingView != customDimmingView) {
70+ [_customDimmingView removeFromSuperview ];
71+ }
72+ _customDimmingView = customDimmingView;
73+ }
74+
75+ - (UIColor *)_dimmingViewColor {
76+ if (self.customDimmingView ) {
77+ BeginIgnorePerformSelectorLeaksWarning
78+ UIView *containerView = [self performSelector: NSSelectorFromString (@" _containerView" )];
79+ EndIgnorePerformSelectorLeaksWarning
80+ UIView *superviewOfDimmingView = containerView.subviews .lastObject ;
81+ UIView *defaultDimmingView = superviewOfDimmingView.subviews .firstObject ;
82+ if (defaultDimmingView) {
83+ defaultDimmingView.alpha = 1 ;
84+ self.customDimmingView .frame = defaultDimmingView.bounds ;
85+ if (self.customDimmingView .superview != defaultDimmingView) {
86+ [defaultDimmingView addSubview: self .customDimmingView];
87+ }
88+ if (self.dimmingViewVisibleChangedBlock ) {
89+ self.dimmingViewVisibleChangedBlock (self.isActive );
90+ }
91+ }
92+ }
93+
94+ return [self qmui_performSelectorToSuperclass: _cmd ];
95+ }
96+
97+ @end
98+
99+ @interface QMUICustomSearchController : UISearchController
48100
49- // iOS7及以前使用这个
50- @property (nonatomic ,strong ) UISearchDisplayController *searchDisplayController;
101+ @property (nonatomic , strong ) UIView *customDimmingView;
102+ @end
103+
104+ @implementation QMUICustomSearchController
105+
106+ - (void )setCustomDimmingView : (UIView *)customDimmingView {
107+ if (_customDimmingView != customDimmingView) {
108+ [_customDimmingView removeFromSuperview ];
109+ }
110+ _customDimmingView = customDimmingView;
111+
112+ self.dimsBackgroundDuringPresentation = !_customDimmingView;
113+ if ([self isViewLoaded ]) {
114+ [self addCustomDimmingView ];
115+ }
116+ }
117+
118+ - (void )viewWillAppear : (BOOL )animated {
119+ [super viewWillAppear: animated];
120+ [self addCustomDimmingView ];
121+ }
122+
123+ - (void )addCustomDimmingView {
124+ UIView *superviewOfDimmingView = self.searchResultsController .view .superview ;
125+ if (self.customDimmingView && self.customDimmingView .superview != superviewOfDimmingView) {
126+ [superviewOfDimmingView insertSubview: self .customDimmingView atIndex: 0 ];
127+ [self layoutCustomDimmingView ];
128+ }
129+ }
130+
131+ - (void )layoutCustomDimmingView {
132+ UIView *searchBarContainerView = nil ;
133+ for (UIView *subview in self.view .subviews ) {
134+ if ([NSStringFromClass (subview.class) isEqualToString: @" _UISearchBarContainerView" ]) {
135+ searchBarContainerView = subview;
136+ break ;
137+ }
138+ }
139+
140+ self.customDimmingView .frame = CGRectInsetEdges (self.customDimmingView .superview .bounds , UIEdgeInsetsMake (searchBarContainerView ? CGRectGetMaxY (searchBarContainerView.frame ) : 0 , 0 , 0 , 0 ));
141+ }
142+
143+ - (void )viewDidLayoutSubviews {
144+ [super viewDidLayoutSubviews ];
145+
146+ if (self.customDimmingView ) {
147+ [UIView animateWithDuration: [CATransaction animationDuration ] animations: ^{
148+ [self layoutCustomDimmingView ];
149+ }];
150+ }
151+ }
152+
153+ @end
154+
155+ @interface QMUISearchController () <UISearchResultsUpdating, UISearchControllerDelegate, QMUISearchResultsTableViewControllerDelegate, UISearchDisplayDelegate>
156+
157+ // iOS 8 及以后使用这个
158+ @property (nonatomic ,strong ) QMUICustomSearchController *searchController;
159+
160+ // iOS 7 及以前使用这个
161+ @property (nonatomic ,strong ) QMUISearchDisplayController *searchDisplayController;
51162@end
52163
53164@implementation QMUISearchController
54165
55166- (instancetype )initWithContentsViewController : (UIViewController *)viewController {
56- if (self = [self init ]) {
167+ if (self = [self initWithNibName: nil bundle: nil ]) {
57168 if (NSStringFromClass ([UISearchController class ])) {
58- // 将definesPresentationContext置为YES有两个作用 :
169+ // 将 definesPresentationContext 置为 YES 有两个作用 :
59170 // 1、保证从搜索结果界面进入子界面后,顶部的searchBar不会依然停留在navigationBar上
60171 // 2、使搜索结果界面的tableView的contentInset.top正确适配searchBar
61172 viewController.definesPresentationContext = YES ;
62173
63- QMUISearchResultsTableViewController *viewController = [[QMUISearchResultsTableViewController alloc ] init ];
64- viewController .delegate = self;
65- self.searchController = [[UISearchController alloc ] initWithSearchResultsController: viewController ];
174+ QMUISearchResultsTableViewController *searchResultsViewController = [[QMUISearchResultsTableViewController alloc ] init ];
175+ searchResultsViewController .delegate = self;
176+ self.searchController = [[QMUICustomSearchController alloc ] initWithSearchResultsController: searchResultsViewController ];
66177 self.searchController .searchResultsUpdater = self;
67178 self.searchController .delegate = self;
68179 _searchBar = self.searchController .searchBar ;
@@ -73,7 +184,7 @@ - (instancetype)initWithContentsViewController:(UIViewController *)viewControlle
73184 [self .searchBar qmui_styledAsQMUISearchBar ];
74185 } else {
75186 _searchBar = [[QMUISearchBar alloc ] init ];
76- self.searchDisplayController = [[UISearchDisplayController alloc ] initWithSearchBar: self .searchBar contentsController: viewController];
187+ self.searchDisplayController = [[QMUISearchDisplayController alloc ] initWithSearchBar: self .searchBar contentsController: viewController];
77188 self.searchDisplayController .delegate = self;
78189 }
79190 }
@@ -96,14 +207,26 @@ - (void)setSearchResultsDelegate:(id<QMUISearchControllerDelegate>)searchResults
96207 }
97208}
98209
99- - (BOOL )active {
210+ - (BOOL )isActive {
100211 if (self.searchController ) {
101212 return self.searchController .active ;
102213 } else {
103214 return self.searchDisplayController .active ;
104215 }
105216}
106217
218+ - (void )setActive : (BOOL )active {
219+ [self setActive: active animated: NO ];
220+ }
221+
222+ - (void )setActive : (BOOL )active animated : (BOOL )animated {
223+ if (self.searchController ) {
224+ self.searchController .active = active;
225+ } else {
226+ [self .searchDisplayController setActive: active animated: animated];
227+ }
228+ }
229+
107230- (UITableView *)tableView {
108231 if (self.searchController ) {
109232 return ((QMUICommonTableViewController *)self.searchController .searchResultsController ).tableView ;
@@ -113,7 +236,7 @@ - (UITableView *)tableView {
113236}
114237
115238- (void )removeDefaultEmptyLabelInSearchDisplayController {
116- // 移除UISearchDisplayController自带的 “无结果”的label
239+ // 移除 UISearchDisplayController 自带的 “无结果”的label
117240 for (UIView *subview in self.searchDisplayController .searchResultsTableView .subviews ) {
118241 if ([subview isKindOfClass: [UILabel class ]]) {
119242 [subview removeFromSuperview ];
@@ -123,6 +246,16 @@ - (void)removeDefaultEmptyLabelInSearchDisplayController {
123246 }
124247}
125248
249+ - (void )setLaunchView : (UIView *)dimmingView {
250+ _launchView = dimmingView;
251+
252+ if (self.searchController ) {
253+ self.searchController .customDimmingView = _launchView;
254+ } else {
255+ self.searchDisplayController .customDimmingView = _launchView;
256+ }
257+ }
258+
126259#pragma mark - QMUIEmptyView
127260
128261- (void )showEmptyView {
@@ -156,7 +289,7 @@ - (void)showEmptyView {
156289
157290- (BOOL )layoutEmptyView {
158291 if ([self .emptyView.superview isKindOfClass: [UITableView class ]]) {
159- // iOS7 UISearchDisplayController里 ,会把emptyView加到searchResultsTableView上,参照showEmptyView里的代码
292+ // iOS7 UISearchDisplayController 里 ,会把emptyView加到searchResultsTableView上,参照showEmptyView里的代码
160293 UITableView *tableView = (UITableView *)self.emptyView .superview ;
161294 CGSize newEmptyViewSize = CGSizeMake (CGRectGetWidth (tableView.bounds ) - UIEdgeInsetsGetHorizontalValue (tableView.contentInset ), CGRectGetHeight (tableView.frame ) - UIEdgeInsetsGetVerticalValue (tableView.contentInset ));
162295 CGSize oldEmptyViewSize = self.emptyView .frame .size ;
0 commit comments