UISearchBar gesture recognizer immediately selects cell in tableview - ios

I got a search bar and a table view setup in my project. Now I want a nice way of dismissing the keyboard just when the user touches the screen anywhere outside of the search bar.
//Search bar tap recognizer
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];
[tap setCancelsTouchesInView:NO];
[self.tableView addGestureRecognizer:tap];
This works so far - if I leave the following line out:
[tap setCancelsTouchesInView:NO];
The tap recognizer kind of overlaps the didSelectRowAtIndexPath method so if I wanted to select a row, I had to sort of slide across the cell to trigger the didSelectRowAtIndexPath method.
Anyways with that line if you tap outside of the search bar, the keyboard disappears but the didSelectRowAtIndexPath is also triggered - since most of the time the user would just tap in the middle of the screen - right at a cell of the table view.
How can I keep the table view method didSelectRowAtIndexPath from being called the first time if the search bar is still "active"? Because I think it's pretty annoying if you just want to dismiss the keyboard and you then the detail view of the tapped cell shows up.

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
if([self.view isFirstResponder])
{
[self.view endEditing:YES];
cell.userInteractionEnabled = NO;
} else {
cell.userInteractionEnabled = YES;
//if you have to do some actions when cell is selected
}
}

In order to dismiss the keyboard just when the user touches the screen anywhere outside of the search bar, you can call "dismiss keyboard" method inside table view didSelectRowAtIndexPath delegate. So it will work as needed.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self dismissKeyboard];
// you can write detail page navigation code here.
}

Related

How to make Segue from TableViewCell image in another View?

How to make Segue from TableViewCell image in another View? http://i.stack.imgur.com/4WOGx.png
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTapped:)];
self.CommentAvatarImageView.userInteractionEnabled = YES;
[self.CommentAvatarImageView addGestureRecognizer:tap];
- (void )imageTapped:(UITapGestureRecognizer *) gestureRecognizer
{
NSLog(#"AVA Tapped");
}
Connect your cell to the view that you want it to segue to when selected. For example, if you want to segue to "nextViewController", then ctrl drag from the respective Table View Cell - Cell in your source Table View to nextViewController. Change the storyboard segue identifier to "nextView".
Then in your didSelectRowAtIndexPath
[self performSegueWithIdentifier:#"nextView" sender:self];

How to deselect UITableViewCell after dismissing UIMenuController?

I've implemented a long press gesture recognizer on a table view cell that shows the UIMenuController and when menu shows, the corresponding table view cell is getting selected which is my requirement.But the problem is when I touches out side,UIMenuController is getting dismissed but the cell is still in selected state.How to deselect the cell when pressing outside
I hope that, you are using the UIPopOverController to show the Menu .
Use the Delegate of popoverControllerDidDismissPopover event to get your solution
- (void) popoverControllerDidDismissPopover:(UIPopoverController *) popoverController {
[myTable deselectRowAtIndexPath:[myTable indexPathForSelectedRow] animated:YES];
}

deselectRowAtIndexPath issue

I have just started working with tableViews, and I have 5 cells in a tableview in a viewController embedded in a navigationController. When a cell is pressed another view is pushed in. My problem is that the cell I press is selected but the selection doesn't go away. I have tried with this code:
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
NewViewController *newViewController = [[NewViewController alloc] init];
newViewController.theTitle = [self.tableView cellForRowAtIndexPath:indexPath].textLabel.text;
[self.navigationController pushViewController: newViewController animated:YES];
}
The tableView is initialized in the viewDidLoad method. Still when I click a cell the new viewController is pushed in but the cell stays selected. What might be the issue here?
You've put your code in the didDeselectRowAtIndexPath - put it in the didSelectRowAtIndexPath. This is an easy mistake to make since didDeselect comes up in code completion before didSelect.
Summary :
You have tableview that is in a ViewController that is in a NavigationController
Use touch a cell
A new ViewController is push on the NavigationController Stack
User hit back and goes back to the screen where you have a tableView
That is what I understand from your question.
At this moment the cell in your tableView should still be selected in order for the user to have a reminder of the last action he as done, but you also want it to get unselected animated at the point ( the mail application is a good example of this behaviour).
So the best place to deselect the cell in your tableView is in - (void)viewDidAppear:(BOOL)animated method of the UIViewController that have the tableview inside it's view. By doing so you will let the user a chance to see the selection before it gently fade away like in mail.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:animated];
}
You can pass nil as argument of deselectRowAtIndexPath, tableView handles it gracefully.
Did you also implement tableView:didSelectRowAtIndexPath:? This method is called every time you tap a cell. So you should put your code there.
The method you are using, tableView:didDeselectRowAtIndexPath: is called whenever a cell is selected and you are tapping a different cell.
I think your problem is that you use wrong method. Change didDeselectRowAtIndexPath to didSelectRowAtIndexPath.

If keyboard is not dismissed, segueing when using a search bar changes destination view controller layout

I have a UITableView where I display a list of chat rooms. I'm also using a search bar to find an specific chat room. When a user taps into a cell, it segues to the chat room conversation, displaying the messages and a text box to send messages.
However, if I seach a chat room using the search bar, when I tap in any cell the segue is done but the layout of the chat room is wrong. The conversation view (custom UITableView) fills the whole screen and the text box (located at the bottom, just in top of a TabBar) doesn't appear.
Trying to solve this issue, I've discovered that I was able to segue correctly when searching if I dismissed the keyboard before tapping into any cell, so it seems that this is only happening when the keyboard is present.
I think I can solve this issue programatically dismissing the keyboard before segueing, but I'm also afraid that maybe I'm doing something wrong with the UISearchBaror the UITableView.
My target project is iOS 5.1 and I've reproduced this issue in an iPad 3 running 5.1, iPad 2 running 6.01 and iPhone simulators.
EDIT
This is the code I'm using to segue
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self.searchController.searchResultsTableView == tableView) {
self.selectedItem = [self.filteredItems objectAtIndex:[indexPath row]];
} else {
self.selectedItem = [self.items objectAtIndex:[indexPath row]];
}
[self performSegueWithIdentifier:#"segueChatRoom" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
[self.view endEditing:YES]; // This line solves the issue
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle: #"Custom title" style: UIBarButtonItemStyleBordered target: nil action: nil];
[[self navigationItem] setBackBarButtonItem: newBackButton];
if ([segue.identifier isEqualToString:#"segueChatRoom"]) {
[segue.destinationViewController setItem:self.selectedItem];
}
}
As you already pointed out you need to resign the first responder (lower the keyboard). Your [self.view endEditing:YES]; is essentially doing this.

UITableView in UIPopover hides content while displaying keyboard

I have a UITableView embedded in a UIPopoverController, as shown below.
When I select a cell, the textField in the cell becomes firstResponder. But instead of keeping the tableview scrolled to the top, all content goes away (even though there are no more than 4 cells). It is impossible to scroll to the top will this happens. After dismissing the keyboard everything is normal again.
The following code does not resolve the problem:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
CRShoppingListItemCell *cell = (CRShoppingListItemCell *) [tableView cellForRowAtIndexPath:indexPath];
cell.itemTextField.enabled = YES;
cell.itemTextField.delegate = self;
[cell.itemTextField becomeFirstResponder];
[tableView scrollToNearestSelectedRowAtScrollPosition:UITableViewScrollPositionNone animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
My guess is you aren't using the UITableViewController. Inside that controller's viewWillAppear it checks for isInViewControllerThatHandlesKeyboardAvoidance (private) and one of those controllers is the popover controller. So if it is that then the keyboard avoiding behaviour you would usually want when the table is full screen is turned off.

Resources