I've seen the question at some places, but not one helped me. Been searching for a while now, so I'll just ask it here.
I have a problem with UISearchDisplayController. The tableView this is working on doesn't take the whole screen, only the right side:
When I tap the searchBar on top it jumps to this:
And when I actually search, this is what I get:
I've tried several 'solutions' like:
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController
*)controller {
controller.searchBar.frame = CGRectMake(300, 20, 744, 44);
}
- (void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView {
tableView.frame = CGRectMake(0, 0, self.carListDropbox.frame.size.width,
self.carListDropbox.frame.size.height);
}
- (void)searchDisplayController:(UISearchDisplayController *)controller willShowSearchResultsTableView:(UITableView *)tableView {
tableView.frame = self.carListDropbox.frame;
}
They don't seem to help AT ALL. Is there any other way I can lock the searchBar (and UISearchDisplayController) into a view?
Thx!
I attempted to make search controllers work in this way and had many problems with the search results tableview not being in the right position and the search bar not being in the right position either. It seems apple's default design for these animates it to the top and does not really give you much information or control over how this is done.
While I'm not sure if there is a way to lock the searchBar into the view(and get the searchResultsTableView to position properly all the time) because there may be a way to do this that I don't know, but I think it is not worth the trouble.
Instead, I'd recommend making your own search bar and searchresultstableview which you can control, animate and position however you'd like whenever you want to, no headache. Make your searchresultstableview hidden until they enter the text field or start typing in it, then show it as desired. If you want it to look the same you'll have to draw your own search icon and search bar which isn't too difficult with UIBezierPath, or you can add your own images.
Related
I have a bit of a problem with my iOS app in xcode. I have a UITableView that loads a few hundred cells. When I scroll down to a specific cell and drill down to detailedviewcontrollers and return again the master view table has returned all the way to the top. I've had a look at the following 2 questions that are similar.
How can I get the UITableView scroll position so I can save it?
Setting scroll position in UITableView
I still can't get these to work. I'm not the most experienced coder so I'm really struggling with this.
I know things like viewWillDisappear and viewDidAppear need to be changed, but I just really can't get much further than that.
On this table I have a reloadData feature so it is possible to pull down the latest data from the server and also a working search bar.
Anyway, a helping hand would be great. Thanks,
Luke
See here you have to first save the scrolled position of tableView i.e. contentOffset of tableView and then reuse it when you are coming back to tableView.
1)When and where you will save it :
When : At the point, when you are drilling down to detailViewController save the contentOffset of tableView
How : float verticalContentOffset = tableView.contentOffset.y;
2) How will you set tableView back to the same scrolled position :
[tableView setContentOffset:CGPointMake(0, verticalContentOffset)];
Hope this will help you.
Sorted!
With a bit of inspiration from Desdenova, whilst at work I had a good think about it and realised what it could be. Remembering that I had a search bar, I had implemented the following code a few months ago to hide it:
[self.tableView setContentOffset:CGPointMake(0,-20) animated:NO];
In naivety I put that in viewDidAppear rather than viewDidLoad. Obviously, this did hide the search bar, but with it being in the wrong void command it did it every time the masterDetailView returned to the top of the stack. So, after moving the above code to viewDidLoad it now still hides it, but only the once.
I'm just spelling it out like this for other beginners, like myself, who may come across the same problem and may just save their sanity!
Thanks to you all for your ideas that helped me out.
+1 to you all!
If anyone is wondering, I tried the solution by Prashant N and it worked. However reloadData don't actually reset the scroll position anymore now, so I didn't have to do anything other than reloadData.
My solution to this problem consisted in scrolling the table to the indexrow of the last item.
private func scrollToItem(item:Int, section:Int bottom:Bool = true, animated:Bool = false) {
let indexPath = NSIndexPath(forRow: item:Int-1, inSection: section)
var position = UITableViewScrollPosition.Bottom
if (!bottom) { position = UITableViewScrollPosition.Top }
self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: position, animated: animated)
}
For some reason this was halfway working for me (sometimes the position would only be approximate). I finally used the following a priori less clean solution
NSIndexPath *firstVisibleIndexPath = [[self.tableView indexPathsForVisibleRows] objectAtIndex:0];
[self.tableView scrollToRowAtIndexPath:self.firstVisibleIndexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];
self.firstVisibleIndexPath = firstVisibleIndexPath;
which worked better.
As mentioned in other comments, scrolling to the top on Back navigation in a UINavigationController is not the default behavior.
Another cause might be that you are setting a cell near the top of the table as first responder in viewWillAppear, e.g. a search box or edit field near the top of your table. UITableViewController will scroll a first responder into view automatically, which is nice. As long as that's what you're trying to do. :) Take care to not set first responder in viewWillAppear unless that's what you want. Cheers, AZ
My decision for a collection:
CGFloat oldCollectionViewHeight = self.messageCollectionView.contentSize.height;
[self.messageCollectionView reloadData];
[self.messageCollectionView layoutIfNeeded];
CGFloat newCollectionViewHeight = self.messageCollectionView.contentSize.height;
if (oldCollectionViewHeight) {
self.messageCollectionView.contentOffset = CGPointMake(0, newCollectionViewHeight - oldCollectionViewHeight);
}
For the table, the principle is the same.
You don’t need to do anything, while you are in the same view controller, your position will be the same. I’m afraid that somewhere in your view controller is being called a reloadData. Search for some method calling scrollToRowAtIndexPath.
I have a UISearchDisplayController working nicely with a UISearchBar. shouldReloadTableForSearchString correctly returns results as the user types, but when the user hits the Search button on the keyboard and searchBarSearchButtonClicked is triggered, something odd happens after the final search results correctly display and the user hits Cancel on the search bar. Once the user reactivates search, the search opens but the cursor doesn't blink, the search results don't display and the keyboard looks locked on every keypress as shown in the attached image. There should be results for "Test", but nothing is happening and something seems to be held up b/c the last pressed key ("T") isn't going back down to the keyboard.
I'm holding off on including code b/c there are a lot of moving parts, but if any code would help, i can quickly include it. Thanks for your help.
UPDATE: it's not just after the user submits the query - if they've touched the resulting searchDisplayController.searchResultsTableView after inputting a query to scroll down through the results, and then hit Cancel, they'll see the frozen cursor and broken search once they activate the searchBar again (same image applies).
SECOND UPDATE: this only happens when I hide / unhide the navbar while search is active in viewWillLayoutSubviews. Any ideas? Really appreciate any help!
-(void)viewWillLayoutSubviews {
if (self.searchDisplayController.isActive && !profileSelected) {
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
else {
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
}
LAST UPDATE: when hide/unhide code is placed into searchDisplayControllerWillBeginSearch and searchDisplayControllerWillHideSearch respectively, the searchBar incorrectly unhides 20px below navbar:
fixed it by adding this code:
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[self.searchDisplayController.searchBar becomeFirstResponder];
}
UISearchDisplayController is using UITableView to show search results. Whenever you scroll or new cells are loaded, viewWillLayoutSubviews is getting called. This is causing the app to freeze. Try moving you setNavigationBarHidden code in a separate method triggered by some other action.
I would like to create a view similar to the App Store's app view on the iPhone :
http://cl.ly/image/0Q1h273v3C00
Basically when you scroll down, part of the header remains fixed at the top :
http://cl.ly/image/3m0I3Y0t1901
Here's the approach I tried, but it doesn't work as expected :
I use a tableView as the 'global view'
In this example, my tableView header would be the top part with the app icon, name ... and UISegmentedControl
Below the header is my regular tableView with cells...
Then, I simply implement the method below :
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// Keeping the menu always visible when user scrolls
// 155 is the original y position of the menu (UISegmentedControl here)
if (scrollView.contentOffset.y > 155) {
self.menuView.frame = CGRectMake(0,
scrollView.contentOffset.y,
self.menuView.frame.size.width,
self.menuView.frame.size.height);
}
else {
self.menuView.frame = CGRectMake(0,
155,
self.menuView.frame.size.width,
self.menuView.frame.size.height);
}
}
The menu remains at the top position just as I want, but still it's not working as expected :
My tableView section headers overlap the menu when I scroll. The only fix I found is to put the header layer at the top using this code :
self.tableView.tableHeaderView.layer.zPosition = MAXFLOAT;
But now the scrollbar is hidden behind the header, so I'm not satisfied with this either
I also tried to use this call in viewDidLoad and ...viewForHeaderInSection
[self.tableView bringSubviewToFront:self.tableView.tableHeaderView];
but it just doesn't work, since the section headers are always added after the tableView header and I haven't found a way to know when the section headers are added, so I can put them behind the tableView header.
When I scroll down more than the menu's initial position, even though the menu remains fixed at the top, I can't click on it, all the events are going to the tableviewcell behind it.
Finally, I want to be able to keep the same header when I click on the other buttons of the UISegmentedControl, just like in the App Store app view, and just change the content below, but I don't want to include the same header each time in each of my views, I would like to make the header generic.
Does anyone have any ideas on how to tackle the problems I'm facing, or a different approach to this ?
P.S : Youtube does kinda the same thing for the channel view, but their solution is not as good as Apple's, as you can't move the content if you start scrolling from the header.
Thanks for your help!
I have a UISearchBar working to dynamically show matching results from a list, but having a nightmare trying to stop the searchResultsTableView from obscuring the resultant UIView, which animates in from the right, when the result is tapped.
The magenta view, (including its shadow subview) and the solid black view should be above the list.
I've tried…
self.searchDisplayController.searchResultsTableView.layer.zPosition = 0;
recipeMeasuresView.layer.zPosition = 1;
recipeListView.layer.zPosition = 2;
…but it's messing up the gestures attached still not displaying the views in the correct order. I've also tried…
[self.view sendSubviewToBack:_searchBar];
[ingredientListView bringSubviewToFront:ingredientListView];
…still no joy. Incidently, I'm also adding – amongst other things – [_searchBar resignFirstResponder]; to my
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
I'm very much an objective-C newbie so all help greatly appreciated.
In case anybody else stumbles across this with similar problems it seems that the issue is due to the searchDisplayController adding it's own view(s) at the top of the stack, therefore obscuring anything that was added to the storyboard.
There would be no way to push anything up or down to change the order because the searchDisplayResultsTable was being added by a different view controller.
The solution I used was to add the views that were being hidden programatically, meaning I could add them as subviews to different parent views depending on what was happening. Probably not the best solution but it does appear to work.
I am trying to get my UITableView to have an "overscroll" search bar. I have followed something pretty similar to this tutorial and it basically works. Unfortunately if the uitableview doesn't have enough content to be scrollable, searchbar cannot be hidden once it is pulled down. Does anyone know how to make a searchbar in a uitableview be hidden by default(which this tutorial does do) and then be able to disappear again when the user "scrolls" down?
try this.
- (void) viewWillAppear:(BOOL)animated{
....
[self hideSearchBar];
}
-(void)hideSearchBar:{
[self.tableView setContentOffset:CGPointMake(0, searchBar.height];
}
if dont work, say something.