2015-12-28 15:50:08 +00:00
|
|
|
/*
|
|
|
|
Copyright 2015 OpenMarket Ltd
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2015-12-28 16:27:39 +00:00
|
|
|
#import "UIViewController+VectorSearch.h"
|
2015-12-28 15:50:08 +00:00
|
|
|
|
|
|
|
#import <objc/runtime.h>
|
|
|
|
|
|
|
|
/**
|
2015-12-28 16:27:39 +00:00
|
|
|
`UIViewController_VectorSearch` is the internal single point storage for the search feature.
|
2015-12-28 15:50:08 +00:00
|
|
|
|
|
|
|
It hosts all required data so that only one associated object can be used in the category.
|
|
|
|
*/
|
2015-12-28 16:27:39 +00:00
|
|
|
@interface UIViewController_VectorSearch : NSObject
|
2015-12-28 15:50:08 +00:00
|
|
|
|
|
|
|
// The search bar
|
|
|
|
@property (nonatomic) UISearchBar *searchBar;
|
|
|
|
|
|
|
|
// Backup of view when displaying search
|
|
|
|
@property (nonatomic) UIView *backupTitleView;
|
|
|
|
@property (nonatomic) UIBarButtonItem *backupLeftBarButtonItem;
|
|
|
|
@property (nonatomic) UIBarButtonItem *backupRightBarButtonItem;
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
2015-12-28 16:27:39 +00:00
|
|
|
@implementation UIViewController_VectorSearch
|
2015-12-28 15:50:08 +00:00
|
|
|
@end
|
|
|
|
|
|
|
|
|
2015-12-28 16:27:39 +00:00
|
|
|
#pragma mark - UIViewController+VectorSearch
|
2015-12-28 15:50:08 +00:00
|
|
|
#pragma mark -
|
|
|
|
|
2015-12-28 16:27:39 +00:00
|
|
|
@interface UIViewController ()
|
2015-12-28 15:50:08 +00:00
|
|
|
|
|
|
|
// The single associated object hosting all data.
|
2015-12-28 16:27:39 +00:00
|
|
|
@property(nonatomic) UIViewController_VectorSearch *searchInternals;
|
2015-12-28 15:50:08 +00:00
|
|
|
|
|
|
|
@end
|
|
|
|
|
2015-12-28 16:27:39 +00:00
|
|
|
@implementation UIViewController (VectorSearch)
|
2015-12-28 15:50:08 +00:00
|
|
|
|
|
|
|
- (UISearchBar *)searchBar
|
|
|
|
{
|
|
|
|
return self.searchInternals.searchBar;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)showSearch:(BOOL)animated
|
|
|
|
{
|
|
|
|
// Backup screen header before displaying the search bar in it
|
|
|
|
self.searchInternals.backupTitleView = self.navigationItem.titleView;
|
|
|
|
self.searchInternals.backupLeftBarButtonItem = self.navigationItem.leftBarButtonItem;
|
|
|
|
self.searchInternals.backupRightBarButtonItem = self.navigationItem.rightBarButtonItem;
|
|
|
|
|
|
|
|
// Reset searches
|
|
|
|
self.searchBar.text = @"";
|
|
|
|
|
|
|
|
// Remove navigation buttons
|
2015-12-28 16:05:00 +00:00
|
|
|
self.navigationItem.hidesBackButton = YES;
|
2015-12-28 15:50:08 +00:00
|
|
|
self.navigationItem.rightBarButtonItem = nil;
|
|
|
|
self.navigationItem.leftBarButtonItem = nil;
|
|
|
|
|
|
|
|
// Add the search bar and
|
|
|
|
self.navigationItem.titleView = self.searchBar;
|
|
|
|
[self.searchBar becomeFirstResponder];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)hideSearch:(BOOL)animated
|
|
|
|
{
|
|
|
|
// Restore the screen header
|
|
|
|
if (self.searchInternals.backupLeftBarButtonItem)
|
|
|
|
{
|
2015-12-28 16:05:00 +00:00
|
|
|
self.navigationItem.hidesBackButton = NO;
|
2015-12-28 15:50:08 +00:00
|
|
|
self.navigationItem.titleView = self.searchInternals.backupTitleView;
|
|
|
|
self.navigationItem.leftBarButtonItem = self.searchInternals.backupLeftBarButtonItem;
|
|
|
|
self.navigationItem.rightBarButtonItem = self.searchInternals.backupRightBarButtonItem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark - UISearchBarDelegate
|
|
|
|
|
|
|
|
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar2
|
|
|
|
{
|
|
|
|
// "Search" key has been pressed
|
|
|
|
[self.searchBar resignFirstResponder];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar2
|
|
|
|
{
|
|
|
|
[self hideSearch:YES];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar2
|
|
|
|
{
|
|
|
|
// Keep the search bar cancel button enabled even if the keyboard is not displayed
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
for (UIView *subView in self.searchBar.subviews)
|
|
|
|
{
|
|
|
|
for (UIView *view in subView.subviews)
|
|
|
|
{
|
|
|
|
if ([view isKindOfClass:[UIButton class]])
|
|
|
|
{
|
|
|
|
[(UIButton *)view setEnabled:YES];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma mark - Internal associated object
|
|
|
|
|
2015-12-28 16:27:39 +00:00
|
|
|
- (void)setSearchInternals:(UIViewController_VectorSearch *)searchInternals
|
2015-12-28 15:50:08 +00:00
|
|
|
{
|
|
|
|
objc_setAssociatedObject(self, @selector(searchInternals), searchInternals, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
|
|
}
|
|
|
|
|
2015-12-28 16:27:39 +00:00
|
|
|
- (UIViewController_VectorSearch *)searchInternals
|
2015-12-28 15:50:08 +00:00
|
|
|
{
|
2015-12-28 16:27:39 +00:00
|
|
|
UIViewController_VectorSearch *searchInternals = objc_getAssociatedObject(self, @selector(searchInternals));
|
2015-12-28 15:50:08 +00:00
|
|
|
if (!searchInternals)
|
|
|
|
{
|
|
|
|
// Initialise internal data at the first call
|
2015-12-28 16:27:39 +00:00
|
|
|
searchInternals = [[UIViewController_VectorSearch alloc] init];
|
2015-12-28 15:50:08 +00:00
|
|
|
|
|
|
|
UISearchBar *searchBar = [[UISearchBar alloc] init];
|
|
|
|
searchBar.showsCancelButton = YES;
|
|
|
|
searchBar.delegate = self;
|
|
|
|
searchInternals.searchBar = searchBar;
|
|
|
|
|
|
|
|
self.searchInternals = searchInternals;
|
|
|
|
}
|
|
|
|
return searchInternals;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|