Search Bar ResignFirstResponder hides Items - iphone

I have this search bar in my app Please see the play, next and previous buttons.
When I search and click on a song from the search items resigning first responder for search bar hides my buttons i.e play, next and previous buttons.
I am using this code
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MPMediaItem * song;
_nowPlayingIndex=indexPath.row;
if (tableView == self.searchDisplayController.searchResultsTableView)
song = searchResults[_nowPlayingIndex];
else
song = _songs[_nowPlayingIndex];
[self.musicPlayer setNowPlayingItem:song];
[self.musicPlayer play];
_playButton.hidden=true;
_pauseButton.hidden=false;
[_mySearchBar resignFirstResponder];
}
Why are my buttons hidden?

Step 1 : What you can do is make a different function for showing and hiding these buttons or any other item.
Step 2 : You can then call these functions wherever required. e.g. Everytime after you have resigned the responder.
Step 3 : You can try setting the table view frame to some less height from code. And then test this thing. Because I think the height of your table view leads to the hiding of those buttons.
e.g. [self.tableView setFrame: CGRectMake(self.view.frame.origin.x, self.searchSong.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height - "button.height" - "navbar.height")];
Step 4 : Also you should debug your code as to when you execute the resignFirstResponder... please check what is the frame of your buttons. This way you will get to know their position.
Its just another way of solving your issue. If you still have questions, you can ask. I hope it works. :)

This is what i was looking for
- (void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView{
CGRect tableFrame= self.searchDisplayController.searchResultsTableView.frame;
tableFrame.size.height=200;
tableFrame.size.width=300;
[self.searchDisplayController.searchResultsTableView setFrame:tableFrame];
[self.searchDisplayController.searchResultsTableView reloadData];
}
and this [[myButton superview] bringSubviewToFront:myButton]; for bringing them to front.

when you search anything apply code to your buttons is search delegate
[grayBar bringSubViewToFront];
or
[yourButton1 bringSubViewToFront];
[yourButton2 bringSubViewToFront];
[yourButton3 bringSubViewToFront];
hope this helps

Related

auto loading data when scrolling down in ios application

I am trying to do the following in my application:
I got my data from an online server, and I put them in cells, What I need is to auto loading the data when scrolling down, means for example 10 cells are loaded when the application is running, then when I scroll down 10 other cells are dynamically loaded.
Like the following example:
Thank You per advance,
You can implement this method inside your view controller and get your next record
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (([scrollView contentOffset].y + scrollView.frame.size.height) >= [scrollView contentSize].height){
// Get new record from here
}
}
This is the simplest way to implement paging. if you want to add Activity indicator at the bottom, you can add it inside the same function.
This automatically loads next fragment of data when user is scrolling near the bottom:
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.contentSize.height - scrollView.contentOffset.y - scrollView.frame.size.height < 60) {
[self loadRequest];
}
}
Try with this:
STableViewController
STableViewController is best for "Load more" and "Pull to refresh" both.
For iOS 6.0, there is a standard control called UIRefreshControl within sdk. apple doc here
and Other here is a step by step Tutorial give here.
Other Open source library available.
EGOTableViewPullRefresh
PullToRefresh
SVPullToRefresh
QBRefreshControl
STableViewController
You can use Following method for this :
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
//put data on your array
[tableView reloadData];
}
For Better Understand See this
You'll also get the Source code from here
Hope this will help.

Differentiate Between UITableView Editing States?

I have been looking at trying to differentiate between editing states in my UITableView.
I need to call a method only when in editing mode after tapping the edit button, so when you get your cell slide in and you see the little circular delete icons but NOT when the user swipes to delete.
Is there anyway I can differentiate between the two?
Thanks.
EDIT:
Solution thanks to Rodrigo
Both each cell and the entire tableview has an 'editing' BOOL value, so I loop through all the cells and if more than one of them is editing then we know the whole table is (the user tapped the edit button), however if only one is editing then we know that the user has swiped a cell, editing that individual one, this lets me deal with each editing state individually!
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
int i = 0;
//When editing loop through cells and hide status image so it doesn't block delete controls. Fade back in when done editing.
for (customGuestCell *cell in self.tableView.visibleCells)
{
if (cell.isEditing) {
i += 1;
}
}
if (i > 1)
{
for (customGuestCell *cell in self.tableView.visibleCells)
{
if (editing)
{
// loop through the visible cells and animate their imageViews
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.4];
cell.statusImg.alpha = 0;
[UIView commitAnimations];
}
}
}
else if (!editing)
{
for (customGuestCell *cell in self.tableView.visibleCells)
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.4];
cell.statusImg.alpha = 1.0;
[UIView commitAnimations];
}
}
}
Even if this post is quite old, the following might be helpful to others:
If you implement the following delegate messages:
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath;
and
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath;
These methods will be called when editing a single line. -[UIViewController setEditing:animated:] will then only get called when the user hits the edit button.
There are one strategy, I do not test now, but maybe work.
You can set the UITableView to be in editing mode and test with isEditing function. But the cell have the same isEditing. So you can check if only one cell is in editing state or all the UITableView.
Check if when you set one cell to be in editing state, the UITableView change to editing state at all.
The solution I chose was to override the action for the edit button to a custom method, say editBtnTapped. In this method I set a variable editButtonPressed, and then, because we overrode the the edit button's action, manually call setEditing:animated:.
In viewDidLoad:
[self.navigationItem.rightBarButtonItem setAction:#selector(editBtnPressed)];
And then the new action method:
- (IBAction) editBtnPressed
{
if ([self isEditing])
{
self.editButtonPressed = NO;
[self setEditing:NO animated:YES];
}
else
{
self.editButtonPressed = YES;
[self setEditing:YES animated:YES];
}
}
Now in setEditing:animated: I check the editButtonPressed flag to determine if I'm in there because of an Edit button press or a simple user swipe. If I'm there due to the Edit button, I add the cell; otherwise I don't.
Keep in mind you may need the flag elsewhere, (e.g. numberOfRowsInSection).
Hope this alternative helps.
Regards,
--John
The only reliable way I have found to do this is to maintain a private flag inEditMode and toggle this flag in setEditing:animated. Then use inEditMode rather than isEditing to check if the table is in edit mode or not.

TableView swipe-to-delete doesn't work

I have an editable, grouped tableView, but swipe to delete doesn't work. It looks like swipe-to-delete is supposed to come along with UITableViewCellEditingStyleDelete, but it doesn't seem to for me. This is my editing style method:
- (UITableViewCellEditingStyle)tableView:(UITableView *)table editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 1)
{
if (indexPath.row < [[device_coordinator getChannelList] count]) return UITableViewCellEditingStyleDelete;
else if (indexPath.row < [[device_coordinator getChannelList] count]+2) return UITableViewCellEditingStyleInsert;
}
return UITableViewCellEditingStyleNone;
}
This makes the table look right. Some cells have insert icons to the left, some have delete icons, as they should. Pressing a delete icon makes the delete confirmation button appear. But a swipe doesn't!
Even if I just return blank, newly allocated cells from my cellForRowAtIndexPath method, it still doesn't work, so it appears that nothing in my cell is causing the problem. The same problem happens on the 4.3 simulator and on my iPod touch 2g.
I think your code is correct but if I understand you right there is a logical error. You want swipe to delete in editing mode which is not possible. Swipe to delete only works when the user is NOT in editing mode.
So you just need to hide/show the editing icons by calling this method.
-(IBAction)edit:(id)sender//action connected to edit button
{
if(yourTableView.editing) [yourTableView setEditing:NO animated:YES];
else [yourTableView setEditing:YES animated:YES];
}
Then swipe to delete will work when there are no icons next to the cells. Hope this helps.

Iphone : How to scroll to the 1st cell of the 2nd section, letting the header of the 1st section visible

I have an UITableView with rows and sections.
I would like to scroll to the first item of the second section, letting the header of the first section visible. Like if I had manually scrolled the list until reaching that state.
---- TOP OF SCREEN ----
Header of first section
Header of the second section
cell 1
cell 2
cell 3
Header of the third section
cell 1
cell 2
...
scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]
does not do the job, it hides the header of the first section.
We're moving on. I found this method based on Kevin's idea. To be able to set animated to YES, I catch the end of animation using a delegate method of UIScrollView. It works. But any solution that would help not doing 2 animations would be greatly appreciated. Any idea about how to do this ?
- (IBAction) scrollToToday:(BOOL)animate {
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:animate];
if (animate == NO) [self showFirstHeaderLine:NO];
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
[self showFirstHeaderLine:YES];
}
- (void) showFirstHeaderLine:(BOOL)animate {
CGRect headerRect = [self.tableView rectForHeaderInSection:1];
CGPoint scrollPoint = headerRect.origin;
scrollPoint.y -= headerRect.size.height;
[self.tableView setContentOffset:scrollPoint animated:animate];
}
Dude to this code, the process when animated is set to YES should loop infinitely beetween scrollViewDidEndScrollingAnimation and showFirstHeaderLine... It loops, yes, but only once... Any idea about why ?
You can grab the rect for the row you want, then subtract the height of the header of the previous section and scroll to that point. Something like the following (untested) should work:
CGRect rowRect = [table rectForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]];
CGRect headerRect = [table rectForHeaderInSection:0];
rowRect.origin.y -= headerRect.size.height;
rowRect.size.height += headerRect.size.height;
[table scrollRectToVisible:rowRect animated:YES]; // UITableView is a subclass of UIScrollView
I tried your code, and it works!!
For the loop question, since you are setting a offset(SetContentOffset), it has nothing to do with the scroll. It is will not call scrollView delegate. SO the scrollViewDidEndScrollingAnimation will be called only once, which has been called from scrollToRowAtIndexPath.

UISearchDisplayContoller – can't prevent table reload on typing in search bar

I'm trying to set up a search display controller to handle async results from a web service. I've got the basic bits in place but have run into a really strange issue that I can't figure out.
Seems like to rig up the search display controller for async you really just need to do two things:
return NO for
searchDisplayController:shouldReloadTableForSearchString,
and
handle searchBarSearchButtonClicked
and fire off the table reload
myself.
I'm doing both of these but what I'm seeing is that the search display controller is reloading the table on the first character typed into the search bar even though I'm returning NO as per #1. It doesn't reload on subsequent characters entered.
So, my question is: how do I keep the search display controller from trying to reload the table while the user is typing? (specifically on that first character entered)
I've seen this issue mentioned as part of a couple of other questions but I have not seen a direct answer to the problem. I'd like to understand what's going on or what I'm doing wrong before I resort to a bunch of UI mangling to work around it.
Here's a quick distillation of my code to show the issue. When I run this and type "abcde" into the search bar, after I type "a" the results display as "a #0", "a #2", etc. They don't update again until I hit the search button then you see "abcde #0", "abcde #1", etc. Desired result is, of course, nothing happens until I hit the search button.
#pragma mark -
#pragma mark UISearchDisplayController Delegate Methods
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
return NO;
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
return NO;
}
#pragma mark -
#pragma mark UISearchBarDelegate Methods
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[self.searchDisplayController.searchResultsTableView reloadData];
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [self.searchDisplayController.searchBar.text stringByAppendingFormat:#" #%d", indexPath.row];
return cell;
}
Thanks! (btw, this is my first question asked here—please let me know if I miss any points of etiquette :)
This is just the way UISearchDisplayController (SDC) works. When the user enters the first character into the searchBar the searchTable is loaded and displayed for the first time causing it to load. The methods "...shouldReloadTableForSearchString" and "...shouldReloadTableForSearchScope" allow you to control whether the searchTable reloads automatically on subsequent chars or a scope change.
I've done both of the following to provide a good user experience on the first character. Slight disclaimer: I do have implementations of both of these that work but this is simply a framework for implementation from my memory. I may have missed a detail but this should get you pretty close.
Option 1: Present a "loading" cell in the searchTable when the first char is typed.
This option allows the SDC to display the searchResultsTableView when the user types the first char, display status as to the current search/filter operation
in the SDC delegate class definition
add the iVar BOOL isLoading
add the iVar UITableView *searchTableView
in searchDisplayController:didLoadSearchResultsTableView
set searchTableView = tableView
in shouldReloadTableForSearchString/Scope
set isLoading = YES
call your method to load data in the background
return NO
when your background filter is complete:
set isLoading = NO
[searchTableView reloadData]
in the various tableView delegate methods respond how you like to show status if there are current search results or results are loading in the background. What I did is:
if there are current search results, show results (even if loading/filtering in the background)
if there are no search results and isLoading == NO return 1 row and show 'No matches' in a cell
if there are no search results and isLoading == YES return 1 row and and show search activity in a cell (I typically use UIActivityIndicatorView)
Option 2: Hide the searchTableView and display an overlay view in it's place until search results are loaded
This option hides the searchTableView when it is first loaded and only redisplays it if when the search/filter is complete. I defined this as an add on to option 1 as they can be done together though to optimize things you may not care about showing search activity in the searchResultsTableView if you are hiding the table and showing the overlay.
in the SDC delegate class definition
same as Option 1
add the iVar UIView *searchTableOverlayView
in searchDisplayController:didLoadSearchResultsTableView
same as Option 1
create a UIView to use as an overlay in place of searchTableView containing whatever UI is appropriate for your app and set it to searchTableOverlayView
in searchDisplayController:didUnloadSearchResultsTableView
release searchTableOverlayView
in 'searchDisplayController:didShowSearchResultsTableView(may be able to do this insearchDisplayController:willShowSearchResultsTableView`
if there are search results to display or isLoading == NO
seachTableOverlayView.hidden == YES
else (if isLoading == YES)
searchTableOverlayView.frame == searchResultsTableView.frame
add seachTableOverlayView as a subview of searchTableVIew.superview
searchTableView.hidden = YES
when your background filter is complete
same as option 1
if there are searchResults to display
searchTableCoverView.hidden = YES
searchResultsTableView.hidden = NO
else
searchResultsTableView.hidden = YES
searchTableCoverView.hidden = NO
in the various tableView delegate methods respond how you like to show status if there are current search results or results are loading in the background. What I did is:
same as option 1
Unfortunately I believe this is just how the UISearchDisplayController functions. You should file a bug report to Apple if you want to request different options for functionality.
The alternative would be to write your own UISearchBar and UITableView combination similar to how UISearchDisplayController works, then you'll get better control.
Hope this helps!
When I faced the same issue I tried to put an overlay view on search result view. That didn't help me. Looks like Apple change the behavior and I saw cell separators shone through my view. Finally I came up with a good approach.
At first my async search class had it's own overlay, progress and other views. UISearchDisplayController was used only for start, end delegate methods calls and sticking to default search flow.
To show view I used any subview I can put a search views on (as an init call):
newView.frame = frame;
[view addSubview:newView];
and then use the subview when changing my search progress views:
if (view == currentView)
return;
view.frame = currentView.frame;
view.alpha = [self getAlphaValueForView:view];
UIView * superView = [currentView superview];
[currentView removeFromSuperview];
currentView = view;
[superView addSubview:currentView];
The problem with empty search result table view blinking appears when I start to use my search content controller in default navigation routine (navigation controller).
So to solve the problem I start using for navigation not a content controller (in this case the default search display controller activating) but an empty controller. And I used empty controllers view as a subview for search views.
So in total: DO NOT use UISearchDisplayController's content view controller in navigation. Use stub view controller. And then use it's view to put your views as subviews.
Worked great for me.
Hide self.searchDisplayController.searchResultsTableView until user presse search button
- (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView;
{
tableView.hidden = YES;
}
After user press the search key, and the search results get ready, make the search result table visible
self.searchDisplayController.searchResultsTableView.hidden = NO;
[self.searchDisplayController reloadData]
This workaround works for me.
Maybe you need to implement UISearchDisplayController and then this function:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText