Has anyone tried using a UISearchDisplayController with a UISearchBar that is a UIBarButtonItem in a UIToolbar?
I would appreciate tips on how to do this successfully.
Currently whenever the search controller pops up it redraws the UISearchBar and I'm struggling to maintain a similar look to the UIToolbar
Usually you don't want to put a search bar inside a toolbar, however, it seems you want to do something similar to what I did.
So here is how I did it, it may be called a hack, but it works like a charm :)
First you have to set it up in interface builder like this:
Notice that the search is not a child of toolbar, instead it is above.
The search bar should have "clear color" background and flexible left, right and width autoresizing masks.
You put a 1-pixel label with black background below the toolbar, ie. [x=0, y=44, width=320 or frame width, height=1], also flexible left, right and width autoresizing masks.This is to hide the one visible pixel you get, after the search display controller shows the table view. Try it without it to understand what I mean.
You setup any tool bar items and be sure to have outlets for them, since you will be needing those.
and now for the code ...
when you start searching:
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller
{
// animate the search bar to the left ie. x=0
[UIView animateWithDuration:0.25f animations:^{
CGRect frame = controller.searchBar.frame;
frame.origin.x = 0;
controller.searchBar.frame = frame;
}];
// remove all toolbar items
[self.toolbar setItems:nil animated:YES];
}
when you end searching
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller
{
// animate search bar back to its previous position and size
// in my case it was x=55, y=1
// and reduce its width by the amount moved, again 55px
[UIView animateWithDuration:0.25f
delay:0.0f
// the UIViewAnimationOptionLayoutSubviews is IMPORTANT,
// otherwise you get no animation
// but some kind of snap-back movement
options:UIViewAnimationOptionLayoutSubviews
animations:^{
CGRect frame = self.toolbar.frame;
frame.origin.y = 1;
frame.origin.x = 55;
frame.size.width -= 55;
controller.searchBar.frame = frame;
}
completion:^(BOOL finished){
// when finished, insert any tool bar items you had
[self.toolbar setItems:[NSArray arrayWithObject:self.currentLocationButton] animated:YES];
}];
}
With this I get the following with a nice animation :)
Related
in my app im tapping on a navigation bar button and as a response i move the view beneath the navigation bar 60 px down (the delta var in the code), and under the view that moves down, appears a UITextField and at the same time show the keyboard.
that's how i achieve it:
-(void)btnSearch_Click:(id)sender{
float delta = _viewBtnSort.frame.size.height;
CGRect rect = rectSearch;
rect.origin.y += delta;
[UIView animateWithDuration:0.3f animations:^{
[_viewSearchResults setFrame:rect];
}completion:^(BOOL finished) {
[buttonSearch setEnabled:NO];
[_txtFieldSearch becomeFirstResponder];
}];}
Problem
it works fine for a few times and then for some unexplained reason(couldnt find so far why), when the keyboard appears it pushes my view back up i and i dont get the effect i want.
anybody got any ideas? thanks!
so i kept looking for a fix, and did it using this iOS8: What's going on with moving views during keyboard transitions? answer.
i changed my constraint instead of the frame and now it seems to work fine.
I am trying to make a UITableView appear when a user taps on a button and disappear when the button is re-tapped.
I implemented the following code but nothing seems to appear when I tap the button.
- (IBAction)dropDown:(UIButton *)sender
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.6];
CGAffineTransform transfrom = CGAffineTransformMakeTranslation(0, 200);
self.markersTableView.transform = transfrom;
self.markersTableView.alpha = self.markersTableView.alpha * (-1) + 1;
[UIView commitAnimations];
}
What may potentially be the issue?
EDIT:
I was able to make the UITableView appear and disappear by adding self.markersTableView.hidden = YES; in viewDidLoad() and self.markersTableView.hidden = NO; in the IBAction method.
However, the table view disappears when I initially tap on the button as shown in the screenshot:
The fading of the rows is an indication it is moving down the screen, and then it disappears.
It only reappears when I re-tap on the UIButton the 2nd time.
Any clues?
Don't use a transform on your table view. That will make it LOOK like it's in a different position, but it won't respond to taps correctly.
Instead, use the newer UIView block-based animation methods and change the view's center.
The code might look like this (if you're NOT using auto-layout)
[UIView AnimateWithDuration: .2
animations: ^
{
CGPoint center = self.markersTableView.center;
center.y += 200;
self.markersTableView.center = center;
}
];
If you're using auto-layout, though, that won't work and you will need to animate the view's position using constraints.
From memory, here's an outline of how to do auto-layout based animations: You would create a vertical position constraint on your table view and connect the constraint to an IBOutlet in your view controller. In your animation code you change the constant of the constraint (the vertical position) and then in the animation block, send the view a needsLayout message.
I have a UITableView which doesn't reach the entire view. Approximatively, the UITableView is two times smaller than the view.
Then, I add "Search Bar and Search Display Controller" to the UITableView from the Object library. So, to visualize, the searchBar appears at the screen's center.
Here's my view :
My problem : When I click into the search field to do my research, the searchBar is going to the top of the view, in place of the navigation bar ! And the transition is very awful... How can I constraint the searchBar to stay in its initial place ?
The problem is related to the search display controller. You don't have the control over the animation and it doesn't seem to handle it well when there's a view sitting on top of your TableView. We had the same exact problem and the easiest way we fixed it is by replacing the Search Display Controller by a simple Search Bar in the Storyboard.
That means your class will now have to implement the delegate method of the search bar to work properly.
To animate properly, simply override the searchBarTextDidBeginEditing and searchBarTextDidEndEditing like so:
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
CGRect tableViewFrame = self.tableView.frame;
tableViewFrame.origin.y = tableViewFrame.origin.y - self.yourHeaderView.bounds.size.height;
[UIView animateWithDuration:0.25
animations:^{ self.tableView.frame = tableViewFrame; }];
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
CGRect tableViewFrame = self.tableView.frame;
tableViewFrame.origin.y = tableViewFrame.origin.y + self.yourHeaderView.bounds.size.height;
[UIView animateWithDuration:0.25
animations:^{ self.tableView.frame = tableViewFrame; }];
}
Simply put, you just move the table view frame over the view based on it's height. The animation makes it smoother and cleaner.
I have standard iPad view controller which has a custom navigation bar at the top. In the xib-file I've added a UISearchBar aligned to the right edge of the view. The search bar is 320px in width. I init a searchdisplaycontroller like this:
// Search display controller
self.mySearchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:_searchBar
contentsController:self];
_mySearchDisplayController.delegate = self;
_mySearchDisplayController.searchResultsDataSource = self;
_mySearchDisplayController.searchResultsDelegate = self;
The problem is that when I press the search bar, the bar resizes to be the full width of the entire view, but keeps its x-position. This means that it stretches far outside the screen. I'm guessing it has something to do with the "Cancel" button that slides in next to a search bar. If I place the search bar to the far left in the screen, it animates to the full width of the screen and the cancel button is visible.
Anyone has a solution for this?
You can animate the frame of your UISearchBar in the searchDisplayControllerWillBeginSearch method to correct its position like this:
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller
{
// animate the search bar to the left ie. x=0
[UIView animateWithDuration:0.25f animations:^{
CGRect frame = controller.searchBar.frame;
frame.origin.x = 0;
controller.searchBar.frame = frame;
}];
// remove all toolbar items if you need to
[self.toolbar setItems:nil animated:YES];
}
and the animate it back again when finished searching:
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller
{
// animate search bar back to its previous position and size
// in my case it was x=55, y=1
// and reduce its width by the amount moved, again 55px
[UIView animateWithDuration:0.25f
delay:0.0f
// the UIViewAnimationOptionLayoutSubviews is IMPORTANT,
// otherwise you get no animation
// but some kind of snap-back movement
options:UIViewAnimationOptionLayoutSubviews
animations:^{
CGRect frame = self.toolbar.frame;
frame.origin.y = 1;
frame.origin.x = 55;
frame.size.width -= 55;
controller.searchBar.frame = frame;
}
completion:^(BOOL finished){
// when finished, insert any tool bar items you had
[self.toolbar setItems:[NSArray arrayWithObjects: /* put your bar button items here */] animated:YES];
}];
}
I have answered a similar question, you can check it here, I've put some images too.
The only thing you have to do is to adapt the code for the iPad.
I'm working on an application and need to hide the UINavigationBar (and toolbar) to provide a fullscreen mode in the in-app browser.
When the app run this code the animation work just fine.
[self.navigationController setNavigationBarHidden:YES animated:YES];
[self.navigationController setToolbarHidden:YES animated:YES];
When I want to exit from the full-screen mode the animation isn't smooth at all.
[self.navigationController setNavigationBarHidden:NO animated:YES];
[self.navigationController setToolbarHidden:NO animated:YES];
During the animation a black rectangle is visible under the navigation bar, I think it is the UIWebView that resize itself (the toolbar animation work just fine.)
Any idea on how I can solve this problem?
Instead of using setNavigationBarHidden:animated: for hiding the navigation bar, try this:
In your view controller's viewDidLoad compute different frames for your navigation bar and your view:
// The normal navigation bar frame, i.e. fully visible
normalNavBarFrame = self.navigationController.navigationBar.frame;
// The frame of the hidden navigation bar (moved up by its height)
hiddenNavBarFrame = normalNavBarFrame;
hiddenNavBarFrame.origin.y -= CGRectGetHeight(normalNavBarFrame);
// The frame of your view as specified in the nib file
normalViewFrame = self.view.frame;
// The frame of your view moved up by the height of the navigation bar
// and increased in height by the same amount
fullViewFrame = normalViewFrame;
fullViewFrame.origin.y -= CGRectGetHeight(normalNavBarFrame);
fullViewFrame.size.height += CGRectGetHeight(normalNavBarFrame);
When you want to go fullscreen:
[UIView animateWithDuration:0.3
animations:^{
self.navigationController.navigationBar.frame = hiddenNavBarFrame;
self.view.frame = fullViewFrame;
} completion:^(BOOL finished) {
}];
When you want to return to normal:
[UIView animateWithDuration:0.3
animations:^{
self.navigationController.navigationBar.frame = normalNavBarFrame;
self.view.frame = normalViewFrame;
} completion:^(BOOL finished) {
}];
Tested this in the iOS 5.1 emulator. Hope you can use that. The "black rectangle" must be the default background color of your window, i.e. a gap between your navigation bar and your view.