I have a tableView list in my IOS app. I wish to search my tableView list with UISearchController. By default the list will display correctly.
When I active search controller (Click on the UISearchController), my existing list will disappear and when I key in related keywords, result will be displayed accordingly.
But when I check on related search result, searchController will be deactivate and back to default list.
Any idea?
- (void)viewDidLoad {
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.delegate = self;
self.searchController.searchBar.delegate = self;
self.searchController.searchBar.barTintColor = ThemeLightGrayColor;
self.searchController.hidesNavigationBarDuringPresentation = NO;
[self.searchController.searchBar.layer setBorderColor:[UIColor colorWithRed:229.0/255 green:229.0/255 blue:229.0/255 alpha:1].CGColor];
[self.searchController.searchBar setPlaceholder:#"Search"];
[self.searchController.searchBar.layer setBorderWidth:0.5];
[self.searchController.searchBar setKeyboardType:UIKeyboardTypeDefault];
[[UITextField appearanceWhenContainedInInstancesOfClasses:#[[UISearchBar class]]] setDefaultTextAttributes:#{ NSFontAttributeName: [UIFont fontWithName:#"Bitter" size:14]}];
[self.searchController.searchBar sizeToFit];
_searchResultArr=[NSMutableArray array];
_tableView.tableHeaderView = ({
UIView *view = [[UIView alloc] init];
view.frame = CGRectMake(0, DCNaviH, 0, self.searchController.searchBar.frame.size.height + 50);
_segPromotion = [[UISegmentedControl alloc] initWithItems:#[#"All",#"Near Me",#"Coming Soon"]];
_segPromotion.selectedSegmentIndex = 0;
_segPromotion.backgroundColor = ThemeWhiteColor;
_segPromotion.frame = CGRectMake(10, self.searchController.searchBar.frame.origin.y+5 + self.searchController.searchBar.frame.size.height , ScreenW-20, 30);
[_segPromotion setTitleTextAttributes:#{NSFontAttributeName : [UIFont fontWithName:#"Bitter" size:13],NSForegroundColorAttributeName: ThemeDarkBlueColor } forState:UIControlStateNormal];
[_segPromotion setTitleTextAttributes:#{NSFontAttributeName : [UIFont fontWithName:#"Bitter" size:13],NSForegroundColorAttributeName : ThemeWhiteColor} forState:UIControlStateSelected];
[_segPromotion addTarget:self action:#selector(SegmentChangeViewValueChanged:) forControlEvents:UIControlEventValueChanged];
[view addSubview:self.searchController.searchBar];
[view addSubview:_segPromotion];
view;
});
[self.view addSubview:_tableView];
}
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
NSString *searchString = searchController.searchBar.text;
[self searchForText:searchString];
[self.tableView reloadData];
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[self updateSearchResultsForSearchController:self.searchController];
}
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope
{
[self updateSearchResultsForSearchController:self.searchController];
}
- (void)searchForText:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[self.searchBar scopeButtonTitles][self.searchBar.selectedScopeButtonIndex]];
}
What you have to do is adding self.searchController.obscuresBackgroundDuringPresentation = NO; when initializing the searchController.
This is because, as you have used [[UISearchController alloc] initWithSearchResultsController:nil], the results will be shown in the same view controller (because of nil parameter). For this reason, if obscuresBackgroundDuringPresentation is set to YES (this is the case by default), the results area won't be touchable.
Related
I have a UIViewController with a SegmentedControl, UITableView and a UISearchController. The SegmentedControl is at the top of the main View with the tableView just beneath it. The searchController's searchBar is placed in the tableView.tableHeaderView and looks like this:
When the searchBar is tapped (made active) it moves down leaving a gap just above:
Also, if the searchBar is active and then the segmentedConrol is tapped (filtering the table data and reloading the tableView) then the tableView loads but with a gap at the top. (I have purposely set the searchBar to hidden when the 'Category' filter is selected.
If the segmentedControl 'Category' is selected when the searchBar is not active this is how it looks (and should look):
I need two things (I think they are related), 1) for the searchBar to NOT move when active and 2) for the searchBar to not be present when 'Category' is selected and for the tableView to have no gap at the top.
.h:
#interface ExhibitorViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UISearchControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating>
{
// DATA
NSMutableArray *arrayOfExhibitors;
NSMutableArray *arrayOfExhibitorsFiltered;
NSMutableArray *arrayOfCategories;
NSMutableArray *arrayOfCategoriesFiltered;
// VARS
int selectedSegment;
float searchBarHeight;
float tableViewY;
NSString *currentCategory;
CGRect tableViewStartRect;
// UI
UISegmentedControl *segmentedControl;
UIView *categorySelectedView;
UIView *headerView;
}
#property (nonatomic, strong) UITableView *tableView;
#property (nonatomic, strong) UISearchController *searchController;
#property (nonatomic, readonly) NSArray *searchResults;
#property (strong, nonatomic) NSString *sponsorsOnly;
#end
.m:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO animated:NO];
if (selectedSegment == 0) {
self.searchController.searchBar.hidden = FALSE;
}
if (!_searchController.searchBar.superview) {
self.tableView.tableHeaderView = self.searchController.searchBar;
}
}
-(void)loadTableView
{
[self printStats:#"loadTableView START"];
searchBarHeight = self.searchController.searchBar.frame.size.height;
Settings *settingsInstance = [Settings new];
if(!_tableView) {
segmentedControl = [UISegmentedControl new];
segmentedControl = [[UISegmentedControl alloc]initWithItems:[NSArray arrayWithObjects:#"Exhibitor", #"Category", nil]];
[segmentedControl setFrame:CGRectMake(0, 0, self.view.frame.size.width, 35)];
segmentedControl.selectedSegmentIndex = 0;
[segmentedControl addTarget:self action:#selector(segmentedControlHasChangedValue) forControlEvents:UIControlEventValueChanged];
self.automaticallyAdjustsScrollViewInsets = YES;
self.edgesForExtendedLayout = UIRectEdgeNone;
self.searchController.hidesNavigationBarDuringPresentation = NO;
//self.definesPresentationContext = NO;
float tvX = self.view.frame.origin.x;
float tvY = self.view.frame.origin.y + segmentedControl.frame.size.height;
float tvWidth = self.view.frame.size.width;
float frameHeight = self.view.frame.size.height;
float tvHeight = self.view.frame.size.height - segmentedControl.frame.size.height;
tableViewStartRect = CGRectMake(tvX, tvY, tvWidth, tvHeight);
_tableView = [UITableView new];
_tableView = [[UITableView alloc] initWithFrame:tableViewStartRect];
//_tableView.contentInset = UIEdgeInsetsMake(0, 0, 44, 0);
_tableView.separatorColor = [UIColor clearColor];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.view addSubview:segmentedControl];
[self.view addSubview:_tableView];
[_tableView setTag:1];
[_tableView setDataSource:self];
[_tableView setDelegate:self];
}
if (!categorySelectedView) {
float levelOneStart = (0);
categorySelectedView = [[UIView alloc] initWithFrame:CGRectMake(0, levelOneStart, self.view.frame.size.width, (screenHeight * 0.05))];
[categorySelectedView setBackgroundColor:[UIColor grayColor]];
[categorySelectedView setTag:4];
MyLabel *catSelectedLabel = [[MyLabel alloc] initWithFrame:categorySelectedView.frame];
[catSelectedLabel setFont:[UIFont systemFontOfSize:[settingsInstance getFontSizeFor:#"Label"]]];
[catSelectedLabel setTag:5];
[catSelectedLabel setBackgroundColor:[UIColor lightTextColor]];
[catSelectedLabel setTextColor:[UIColor darkGrayColor]];
UIButton *categoryBackButton = [[UIButton alloc] initWithFrame:CGRectMake((screenWidth * 0.6), levelOneStart, (screenWidth * 0.4), (screenHeight * 0.05))];
[categoryBackButton setTitle:#"^ Back ^" forState:UIControlStateNormal];
[categoryBackButton setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal];
[categoryBackButton addTarget:self action:#selector(resetTableViewCategories) forControlEvents:UIControlEventTouchUpInside];
[catSelectedLabel addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(resetTableViewCategories)]];
[categoryBackButton.titleLabel setFont:[UIFont systemFontOfSize:[settingsInstance getFontSizeFor:#"Label"]]];
[categorySelectedView addSubview:catSelectedLabel];
[categorySelectedView addSubview:categoryBackButton];
[categorySelectedView setHidden:TRUE];
}
if (!headerView) {
headerView = [[UIView alloc] initWithFrame:CGRectMake(0, (0), screenWidth, (searchBarHeight))];
[headerView addSubview:categorySelectedView];
[self.view addSubview:headerView];
[headerView setBackgroundColor:[UIColor purpleColor]];
[self.view sendSubviewToBack:headerView];
}
[self.view setTag:11];
tableViewY = _tableView.frame.origin.y;
[self printStats:#"loadTableView END"];
}
-(UISearchController*)searchController
{
if (!_searchController) {
_searchController = [[UISearchController alloc]initWithSearchResultsController:nil];
_searchController.searchResultsUpdater = self;
_searchController.dimsBackgroundDuringPresentation = NO;
_searchController.searchBar.delegate = self;
[_searchController.searchBar sizeToFit];
}
return _searchController;
}
-(void)segmentedControlHasChangedValue
{
[self.searchController setActive:NO];
if ((segmentedControl.selectedSegmentIndex == 0)) {
selectedSegment = 0;
currentCategory = #"";
[self resetTableViewExhibitors];
[_tableView setContentOffset:CGPointMake(0, -1) animated:NO];
} else {
selectedSegment = 1;
[self resetTableViewCategories];
[_tableView setContentOffset:CGPointMake(0, -1) animated:NO];
//[_tableView setContentOffset:CGPointMake(0, 56) animated:NO];
[_tableView setTableFooterView:nil];
}
[_tableView reloadData];
}
I have tried changing the insets of various views and forcing a manual changes to the frames of various views (this is the closest thing to a fix but seems very hacky). What am I doing wrong?
Edit: Have also tried :
-(void)segmentedControlHasChangedValue
{
[self.searchController setActive:NO];
if ((segmentedControl.selectedSegmentIndex == 0)) {
selectedSegment = 0;
currentCategory = #"";
[self resetTableViewExhibitors];
[_tableView setContentOffset:CGPointMake(0, -1) animated:NO];
} else {
selectedSegment = 1;
[_searchController dismissViewControllerAnimated:NO completion^() {
[self resetTableViewCategories];
[_tableView setContentOffset:CGPointMake(0, -1) animated:NO];
[_tableView setTableFooterView:nil];
}];
}
[_tableView reloadData];
}
Because you use UISearchController so searchBar will always move when it actives. To avoid it, use UISearchBar. And when you use UISearchBar, it's easy to hide when you select Category tab
question one :
when a SearchController.searchBar as a tableview.tableHeaderView, and tableview have backgroundColor
why it has a strange color: image
question two :
How to use a SearchController.searchBar as a tableview.sectionHeader
when i try do it, my tableView will be so crazy image
code snippet :
- (UISearchController *)searchController{
if (!_searchController) {
_searchController = [[UISearchController alloc] initWithSearchResultsController: self.resultVC];
_searchController.searchResultsUpdater = self;
_searchController.delegate = self;
self.definesPresentationContext = YES;
// 是否添加半透明覆盖
_searchController.dimsBackgroundDuringPresentation = YES;
// 是否隐藏导航栏
_searchController.hidesNavigationBarDuringPresentation = YES;
// 可以通过此种方式修改searchBar的背景颜色
_searchController.searchBar.barTintColor = GL_NAVBAR_COLOR;
UIImageView *barImageView = [[[_searchController.searchBar.subviews firstObject] subviews] firstObject];
barImageView.layer.borderColor = GL_NAVBAR_COLOR.CGColor;
barImageView.layer.borderWidth = 1;
// 可以通过此种方式可以拿到搜索框,修改搜索框的样式
UITextField *searchField = [[[_searchController.searchBar.subviews firstObject] subviews] lastObject];
searchField.backgroundColor = [UIColor yellowColor];
searchField.placeholder = #"请输入搜索内容";
}
return _searchController;
}
- (void)configureUI{
self.tableView = [[UITableView alloc] initWithFrame: self.view.bounds style:UITableViewStylePlain];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.view addSubview: self.tableView];
self.tableView.backgroundColor = backgroundColor;
self.searchController.searchBar.frame = CGRectMake(0, 0, ScreenWidth, 44);
#if tableHeaderViewSearchBar
self.tableView.tableHeaderView = self.searchController.searchBar;
#endif
}
#if !tableHeaderViewSearchBar
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 50;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return self.searchController.searchBar;
}
#endif
You can place the UISearchBar of UISearchController in the navigation bar so that it remains fixed at the top.
So, just add below code at the end of configureUI method and remove last 2 lines of code inside the same method.
self.searchController.hidesNavigationBarDuringPresentation = NO;
self.searchController.searchBar.searchBarStyle = UISearchBarStyleMinimal;
self.navigationItem.titleView = self.searchController.searchBar;
self.definesPresentationContext = YES;
I have a provisional idea:
- (void)viewDidLoad {
[super viewDidLoad];
[self.searchController.searchBar sizeToFit];
self.tableView.frame.origin.y = CGRectGetMaxY(self.searchController.searchBar.frame);
[self.view addSubview: self.searchController.searchBar];
}
To answer question one: you need to set tableView.backgroundView
UIView *tableBackgroundView = [[UIView alloc]initWithFrame:self.tableView.bounds];
tableBackgroundView.backgroundColor = GL_BACKGROUD_COLOR;
self.tableView.backgroundView = tableBackgroundView;
custom UITextField: In the click TextField input,After the keyborad popup,enter the background to get enter foreground again,The app crash!
if you don't click TextField input,background or foreground conversion ,It is normal;Part of the code:
#implementatio BKSearchViewController
- (void)setNavgationView {
BKSearchBar *searchBar = [[BKSearchBar alloc] initWithFrame:CGRectMake(20, 27, kScreenWidth - 90, 30)];
searchBar.placeholder = #"输入昵称/拜托号";
searchBar.delegate = self;
[searchBar setKeyboardType:UIKeyboardTypeDefault];
[searchBar setReturnKeyType:UIReturnKeySearch];
[searchBar setPlaceholderColor:kcallColor(#"a4a4a4")];
[searchBar setPlaceholderFont:kFont(14)];
[searchBar addTarget:self action:#selector(SearchTextFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
[navgationView addSubview:searchBar];
}
#end
//BKSearchBar The key code
#implementation BKSearchBar
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// 设置背景
self.backgroundColor = kcallColor(#"7d1d57");
self.returnKeyType = UIReturnKeySearch;
// 设置内容 -- 垂直居中
self.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
[self UI];
}
return self;
}
- (void)UI{
// 设置左边显示一个放大镜
UIImageView *leftView = [[UIImageView alloc] init];
omit...
//右边的view
UIImageView *rightView = [[UIImageView alloc] init];
omit...
}
- (CGRect)placeholderRectForBounds:(CGRect)bounds{
CGRect rect = CGRectMake(self.leftView.right, (self.height - 24) / 2, bounds.size.width, 14);
return rect;
}
- (void)clearText{
self.text = nil;
}
- (void)setPlaceholderColor:(UIColor *)color{
[self setValue:color forKeyPath:#"_placeholderLabel.textColor"];
}
- (void)setPlaceholderFont:(UIFont *)font{
[self setValue:font forKeyPath:#"_placeholderLabel.font"];
}
Thank all!The problem is resolved!because of the runtime!
+ (void)swizzleInstanceMethod:(Class)class originSelector:(SEL)originSelector otherSelector:(SEL)otherSelector
{
Method otherMehtod = class_getInstanceMethod(class, otherSelector);
Method originMehtod = class_getInstanceMethod(class, originSelector);
// 交换2个方法的实现
method_exchangeImplementations(otherMehtod, originMehtod);
}
I have added a UISearchBar programatically to my UITableView, it was showing perfectly fine untill I decided to add an offset to my UITableView to hide the UISearchBar when the view is loaded. I would like help displaying it again.
This is what my code looks like.
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.contentOffset = CGPointMake(0.0f, 44.0f);
mySearchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 44.0f)];
mySearchBar.autocorrectionType = UITextAutocorrectionTypeNo;
mySearchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
mySearchBar.keyboardType = UIKeyboardTypeAlphabet;
mySearchBar.delegate = self;
self.tableView.tableHeaderView = mySearchBar;
// Create the search display controller
UISearchDisplayController *searchController = [[UISearchDisplayController alloc] initWithSearchBar:mySearchBar contentsController:self];
searchController.searchResultsDataSource = self;
searchController.searchResultsDelegate = self;
I am not really sure where to go to from here.
This code will work in both iOS6 and iOS7.
Note that in iOS7 you will loose transparency of NavigationBar
if ([self respondsToSelector:#selector(edgesForExtendedLayout)]) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
[self.tableView setContentOffset:CGPointMake(0, mySearchBar.frame.size.height)];
If you want to save default transparency in iOS7 use this code:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if ([self respondsToSelector:#selector(edgesForExtendedLayout)]) {
[self.tableView setContentOffset:CGPointMake(0, -20)];
}
else {
[self.tableView setContentOffset:CGPointMake(0, mySearchBar.frame.size.height)];
}
}
I have a UITableView which has some custom styling. This table view appears in two places in the app, one of which is inside a UIPopoverController. However when the tableview is inside the popover it takes on the default tableview styling as stated in the UI Transition Guide under "Popover".
The problem I have is that there appears to be nowhere to change this behaviour. Regardless of where I try and modify properties of the tableview the view inside the popover doesn't change.
Anyone dealt with this issue before or have any ideas?
Here is the init method of LibraryProductView where I create the table view:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.sectionOrdering = [NSArray arrayWithObjects:
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_DESCRIPTION],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_DOCUMENTS],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_ACTIVE_INGREDIENTS],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_RELATED_PRODUCTS],
[NSNumber numberWithInt:LIBRARY_PRODUCT_SECTION_RELATED_DOCUMENTS], nil];
self.backgroundColor = [UIColor whiteColor];
self.tableView = [[UITableView alloc] initWithFrame:CGRectInset(self.bounds, 10, 0) style:UITableViewStyleGrouped];
self.tableView.backgroundColor = [UIColor whiteColor];
self.tableView.dataSource = self;
self.tableView.delegate = self;
self.tableView.separatorColor = [UIColor clearColor];
self.tableView.showsVerticalScrollIndicator = NO;
[self addSubview:self.tableView];
}
return self;
}
Here is where the containing view (LibraryProductView) is added to the popover:
- (IBAction)didTouchInformationButton:(id)sender
{
if (_infoPopover != nil && _infoPopover.isPopoverVisible)
{
[_infoPopover dismissPopoverAnimated:YES];
return;
}
CGSize preferredSize = CGSizeMake(600.0f, 500.0f);
LibraryProductViewController* productController = [[[LibraryProductViewController alloc] initWithPreferredSize:preferredSize] autorelease];
productController.filterByMyCompany = NO;
productController.product = _activityInput.product;
UINavigationController* nav = [[[UINavigationController alloc] initWithRootViewController:productController] autorelease];
nav.title = _activityInput.product.name;
RELEASE(_infoPopover);
_infoPopover = [[UIPopoverController alloc] initWithContentViewController:nav];
_infoPopover.popoverContentSize = CGSizeMake(preferredSize.width, preferredSize.height + 46);
[_infoPopover presentPopoverFromRect:_infoButton.frame inView:_infoButton permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
}
The LibraryProductView is created within viewDidLoad method of LibraryProductViewController.
- (void)viewDidLoad
{
[super viewDidLoad];
self.libraryProductView = [[LibraryProductView alloc] initWithFrame:(usingPreferredSize ? CGRectMake(0.0, 0.0, preferredSize.width, preferredSize.height) : self.view.bounds)];
self.libraryProductView.dataSource = self;
self.libraryProductView.delegate = self;
[self.view addSubview:self.libraryProductView];
}
To set properties for the TableView you might do so in
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
[tableView setBackgroundColor:[UIColor redcolor]];
[tableView setSeparatorColor: [UIColor blueColor]];
return 1;
}
This, of course, assumes you have set UITableViewDataSource in your .h file