Why my UISearchBar`s frame is changed by the UISearchDisplayController - ios

I write UISearchBar in my TopBar.m like this:
_tempSearchBar =[[UISearchBar alloc]initWithFrame:CGRectMake(44, 0, 320 - 44, 43)];
_tempSearchBar.barStyle=UIBarStyleDefault;
_tempSearchBar.placeholder=#"搜索";
[self addSubview:_tempSearchBar];
the result is like this, it is right.
and then I write UISearchDisplayController in another class like this:
_topBar.tempSearchBar.delegate = self;
_searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:_topBar.tempSearchBar contentsController:self];
[_searchDisplayController setDelegate:self];
[_searchDisplayController setSearchResultsDataSource:self];
the UISearchBarDelegate is like this:
#pragma mark -
#pragma mark UISearchBarDelegate
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
[_searchDisplayController setActive:YES animated:YES];
}
when I click the UISearchBar , it show like this , the searchBar`s frame is changed.why?
when I cancel the UISearchDisplayController it is like this :
why the frame is changed? The width is changed from 320-44 to 320 by the UISearchDisplayController?
thanks.

UISearchDisplayController expands the search bar to the width of its superview. The simplest solution that I have found is to place the search bar inside another UIView that has the width I am looking for.

The searchBar's frame is changed by the UIKit, so I changed the searchBar's frame back myself.
I changed the searchBar's frame in the below delegate.
One is UISearchBar's delegate:
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
[searchBar setFrame:CGRectMake(44, 0, 320 - 44, 43)];
}
Another is UISearchDisplayController's delegate:
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller{
[controller.searchBar setFrame:CGRectMake(44, 0, 320 - 44, 43)];
[self.searchDisplayController.searchResultsTableView setDelegate:self];
}
It can work and I can get the right frame, but when I click the searchBar it will shake a little.
It is not the best way to do it, but it can work. Does anyone have a better method?
Update:
I have debugged the UISearchBar and UISearchDisplayController for a few hours, but it has a little bug: When I endEditing the searchBar's width will become 320px, and then will become my width. I can not change the cancelButton's background color. So I wrote a custom SearchDisplayController, with a UISearchBar property and a UITableView property. It works well for me.

Call the delegate method
- (void) searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller
{
[controller.searchBar setFrame:CGRectMake(0,31, 320 , 43)];
[self.searchDisplayController.searchResultsTableView setDelegate:self];
}

You can handle the cancel button of searchBar using - (void)setShowsCancelButton:animated:
If you do not want to show cancel button (as cancel button will change the frame of searchBar)
just write this in delegate
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
[searchBar setShowsCancelButton:NO animated:YES];
}
Updated:
An only possible solution seems to be finding the cancel button from SearchBar view hierarchy and hiding it.
for (UIView *possibleButton in searchBar.subviews)
{
if ([possibleButton isKindOfClass:[UIButton class]])
{
UIButton *cancelButton = (UIButton*)possibleButton;
cancelButton.hidden = YES;
break;
}
}

Related

searchDisplayControllerWillEndSearch goes out of the UIView when end searching

I've a UIView in which I've placed a UISearchBar and a UIButton below are the screenshots that explains the problem:
^This is how it appears when I first run the app
^This is how it gets when I want to enter the text
^Finally this is the size it gets after I end the searchThe most important point here is that I'm not using UINavigationBar the red is a UIView. I've haven't coded anything for it's UI, I just placed it in the .xib and set it via autoResizing. They only this I wrote for UISearchBar was [_searchBarTop setBackgroundImage:[UIImage new]]; which was just to get the background image vanished.I've tried self.searchBarTop.clipsToBounds = YES; and this
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller
{
self.searchDisplayController.searchBar.translatesAutoresizingMaskIntoConstraints = YES;
[self.searchDisplayController setActive:NO animated:YES];
}
I'm using searchdisplaycontroller and want to use that
But it's still the same. Any suggestions?
If you're using a simple UISearchBar in a UIView, you don't need to use UISearchController per sè. You can simply use UISearchBar and it's respective delegates instead.
As for the resizing issue, I think you have the autoresizing at flexible width, whereas you need static width, with static sides. Apply this to both your UIView and the embedded UISearchBar. That should fix your issue. Let me know if the problem persists.
If autoresizing doesn't work, you can just force it back like this:
-(void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
CGRect frame = self.searchBarTop.frame;
frame.origin.x = 33;
frame.size.width = self.view.frame.size.width - 41;
[UIView animateWithDuration:0.5 animations:^{
self.searchBarTop.frame = frame;
}];
});
}
UISearchDisplayController was first deprecated in iOS 8.0, as indeed was UISearchDisplayDelegate. You should use UISearchController its delegate, UISearchControllerDelegate and its searchBar property instead.
EDIT - Add Example
// your class needs to conform to the following protocols
<UISearchResultsUpdating, UISearchControllerDelegate>
// define property for your search controller
#property (nonatomic) UISearchController *mySearchController;
// instantiate the search controller - in viewDidLoad should work
// if you want to handle results manually the searchResultsController can be nil, or you can set it to
self.mySearchController = [[UISearchController alloc]initWithSearchResultsController:nil];
[self.mySearchController.searchBar sizeToFit];
self.mySearchController.searchResultsUpdater = self;
self.mySearchController.delegate = self;
self.mySearchController.dimsBackgroundDuringPresentation = NO;
// add the searcher to a properly constrained "Container" or "wrapper" UIView
[self.containerView addSubView:self.mySearchController.searchBar];
[self.mySearchController.searchBar sizeToFit];
self.definesPresentationContext = YES;
you can then respond to the input in the search bar by implementing the UISearchResultsUpdating protocol's required method:
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController{
NSString *text = searchController.searchBar.text;
/// do whatever you need to with the text typed in to the search bar
}
And Finally, always read Apple's documentation

UISearchDisplayController table view overlapping search bar

I have a UITableViewController subclass, displayed in a modal view on an iPad. The view controller has a UISearchDisplayController subclass with a UISearchBar included in the header view of the table.
The subclassed UISearchDisplayController is called NoAnimationSearchDisplayController and I have overridden the - (void)setActive:(BOOL)visible animated:(BOOL)animated
method to prevent the search bar from animating into the navigation bar when it's set to active. The method override is below...
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
if (self.active == visible) {
return;
}
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
if (visible) {
[self.searchBar becomeFirstResponder];
} else {
[self.searchBar resignFirstResponder];
}
}
The problem I'm having, is that when I have searched, and results are displayed in my search display controller's table view, everything looks fine untill i try to scroll down the list, at this point the content within the cells appears above the search bar, as shown in the following screen:
The search bar is set to UISearchBarStyleMinimal and transparency is enabled. Can anyone let me know how to stop this content overlapping the search bar? Ideally the content would disappear under the search bar as if it was the end of the view.
The answer was to manually change the frame of the table view provided by the UIsearchDisplayController in the appropriate delegate method...
- (void)searchDisplayController:(UISearchDisplayController *)controller willShowSearchResultsTableView:(UITableView *)tableView {
/**
* Remove content inset automatically set by UISearchDisplayController as we are forcing the
* search bar to stay in the header view of the table, and not go into the navigation bar.
*/
[tableView setContentInset:UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f)];
/**
* Recalculate the bounds of our table view to account for the additional 44 pixels taken up by
* the search bar, but store this in an iVar to make sure we only adjust the frame once. If we
* don't store it in an iVar it adjusts the frame for every search.
*/
if (CGRectIsEmpty(_searchTableViewRect)) {
CGRect tableViewFrame = tableView.frame;
tableViewFrame.origin.y = tableViewFrame.origin.y + 44;
tableViewFrame.size.height = tableViewFrame.size.height - 44;
_searchTableViewRect = tableViewFrame;
}
[tableView setFrame:_searchTableViewRect];
}
Be sure the search bar is not translucent enabled ( on storyboard/xib ) or by code.
Then make the background to white or whatever color you want.

Why does UIKeyboard appear when press cancel button on UISearchbar?

I am using following code for adding UISearchBar in iOS7 and UISearchBar appearance is fine.But problem is when press cancel button on UISearchBar then UIKeyboard appeared.Why its happen?Please help me.
CGRect searchFrame = CGRectMake(self.view.bounds.origin.x, 64, self.view.bounds.size.width, 44.0f);
self.mySearchBar = [[UISearchBar alloc]initWithFrame:searchFrame];
self.mySearchBar.delegate = self;
self.mySearchBar.searchBarStyle = UISearchBarStyleDefault;
self.mySearchBar.placeholder = #"search items;
self.mySearchBar.showsCancelButton = YES;
[self.view addSubview:self.mySearchBar];
Implement the searchBarCancelButtonClicked: UISearchBarDelegate method. If you want the keyboard to go away you would do something like:
- (void) searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
}
I got your issue now.
When there is not text entered at that time cancel button will be disabled. So if you try to press it than it will consider SearchBar text area & Keyboard will appear.
While you enter the text than Cancel button will be active & than it will work.
Hope you'll get the solution from this.

iOS 7 UISearchBar right spacing

Don't know why, my search bar in iOS 7 is leaving a right space. It's ok in iOS 6.
I know it has something to do with the section index, because if I remove it the space disappears, but I don't know how to fix it. Any thoughts?
Embed your UISearchBar in a UIView and then add that as the tableHeaderView. Structuring it that way in a storyboard worked for me. I'm guessing iOS resizes the UISearchBar in the tableHeaderView, but leaves a basic UIView alone (and doesn't bother to look inside it).
You might also want to make the section index transparent, which I did with:
[[UITableView appearance] setSectionIndexBackgroundColor:[UIColor clearColor]];
[[UITableView appearance] setSectionIndexTrackingBackgroundColor:[UIColor clearColor]];
Until a better answer appears, I just manually changed the frame of the search bar like this:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
CGRect barFrame = self.searchBar.frame;
barFrame.size.width = self.view.bounds.size.width;
self.searchBar.frame = barFrame;
}
I had this same issue with the iPhone 6/ 6Plus when using a SearchDisplayController. (Using Swift)
I tried setting the frame of the search bar but with no luck but i noticed that if i tapped on the textField of the UISearchBar and then cancelled it then it would take on the proper size of the view. I therefore managed to fix the issue by calling the code below in ViewDidLoad of the viewController using the search.
self.searchController.setActive(true, animated: false)
self.searchController.setActive(false, animated: false)
self.contactsTableView.sectionIndexBackgroundColor = [UIColor clearColor];
The reason for that white edge is because your index layer has a white background and is on top of the search bar. This should be sufficient.
Add the search bar inside a UIView put as tableView's header view. Set the tableview's sectionIndexBackgroundColor to clear color because it covers the header.
Tested with iOS 7, 7.1;
Because the table view always leaves 15px on the right for section Indexes View, so you should resize the Seach bar after reloading the table view
First:
self.tblData.sectionIndexBackgroundColor = [UIColor clearColor]; //(iOS >= 7 only)
Cheating time:
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
[self performSelector:#selector(resizeSearchBar) withObject:nil afterDelay:0.01];
}
- (void) resizeSearchBar
{
CGRect frame = self.searchBar.frame;
if (frame.size.width < self.tblData.frame.size.width) {
frame.size.width = self.tblData.frame.size.width;
}
self.searchBar.frame = frame;
}
- (void) reloadTableData // call it anytime you want to reload table view
{
[self.tblData reloadData];
[self performSelector:#selector(resizeSearchBar) withObject:nil afterDelay:0.01];
}
Suggest
Dont cheat like me, just do the simpler way:
self.searchBar.searchBarStyle = UISearchBarStyleMinimal; // iOS >= 7 only
I also attached a UISearcBar in my application, and nothing is wrong there even my application supports rotation also.
Could you try removing and re creating UISearchBar in storyboard/xib
I added the search bar as a subview of the top-level view instead of the table view. Used autolayout to pin the searchbar to the top guide, and a vertical space constraint of 0 between the search bar and the table view.
The accepted solution with the method viewDidLayoutSubviews makes the screen flicker.
Instead what I did was create a subclass of UISearchBar that simply does this:
FullWidthSearchBar.h:
#interface FullWidthSearchBar : UISearchBar
#end
FullWidthSearchBar.m:
#import "FullWidthSearchBar.h"
#implementation FullWidthSearchBar
- (void)setFrame:(CGRect)frame {
frame.size.width = self.superview.bounds.size.width;
[super setFrame:frame];
}
#end
And then I assigned that class to the search bar on my xib:
The problem is the right white block, so if we change the block color the same as the search bar background, it looks normal.
just
if (IOS7) {
self.tableview.backgroundColor = [UIColor colorWithPatternImage:self.searchBar.backgroundImage];
}

Search Bar Cancel Button don´t work in ios 7 sometimes

Cancel button in search bar don´t work in iOS 7 when search bar is initially hidden.
I follow this tutorial to create a search bar in tableview:
raywenderlich tutorial
There are a example project in this tutorial, is better use this project than my explanation :)
In iOS 5 and 6 works fine.
I have reviewed all delegates.
There are two possibilities. The first is to press the button when the bar is hidden, the second is to press the button when the bar is displayed (moving the table down with a gesture you can see the search bar)
If search bar is hidden initially cancel button don´t work, it don't call calcel delegate method:
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
Sorry I can not explain it better.
Thanks
I googled all over internet and couldn't find a solution. so i changed the UItableview behaviour.
instead of [searchBar becomeFirstResponder]; I scroll down the tableview.
- (IBAction)goToSearch:(id)sender {
scroll down to show the table.
// CGRect newBounds = self.tableView.bounds;
// newBounds.origin.y =0;
//
// self.tableView.bounds = newBounds;
//[searchBar becomeFirstResponder];
CGPoint contentOffset=self.tableView.contentOffset;
contentOffset.y=0;
[self.tableView setContentOffset:contentOffset animated:YES];
}
in my ViewDidload:
// CGRect newBounds = self.tableView.bounds;
// newBounds.origin.y = newBounds.origin.y + searchBar.bounds.size.height;
// self.tableView.bounds = newBounds;
CGPoint contentOffset=self.tableView.contentOffset;
contentOffset.y=self.tableView.bounds.origin.y + searchBar.bounds.size.height;
self.tableView.contentOffset=contentOffset;
If found for some reasons, in iOS 7 , change table view bounds cause search bar to disappear.
Hope that helps.
That code work for me on iOS7:
- (IBAction)goToSearch:(id)sender {
[self.tableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
[candySearchBar becomeFirstResponder];
}
put this code in your project it will work i have tested and it is working correctly
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchbar
{
[searchbar resignFirstResponder];
for (UIView *possibleButton in searchbar.subviews)
{
if ([possibleButton isKindOfClass:[UIButton class]])
{
UIButton *cancelButton = (UIButton*)possibleButton;
cancelButton.enabled = YES;
break;
}
}
}
This problem seems to come from the new behaviour of the translucent property in a navigation bar.
Since iOS 7 navigation bars are translucent by default. And it looks like it's overlapping the search bar when you display it after pressing a button.
Try to set in your controller:
float osVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (osVersion >= 7.0)
{
self.navigationController.navigationBar.translucent = NO;
}
This should quickly solve the problem.
But I think for a better fix you should see the iOS 7 transition guide where they explain how to handle translucent navigation bars.
Hope that helps.
I assume you have set _searchBar.delegate = self and implemented UISearchBarDelegate in your class.
This is how you do it:
- (void) searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
[searchBar setShowsCancelButton:YES animated:YES];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{ // called when cancel button pressed
searchBar.text = nil;
//hide cancel button
[_searchBar setShowsCancelButton:NO animated:YES];
[searchBar resignFirstResponder];
}

Resources