tableviewcontroller within container view controller: programatically selecting uitableviewcell, highlighting blinks - ios

I am trying to programatically highlight a table view cell and trigger the selection logic by doing the following
NSIndexPath*indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[self tableView:self.tableView didSelectRowAtIndexPath:indexPath];
The row highlights only for a split second. I want it to stay highlighted until I select another row.
I tried adding these lines
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath: indexPath];
cell.highlighted = YES;
but when I did this, the highlight remained even when I clicked on another row and did not go away until I clicked the first row again.
Any ideas?

Try calling selectRowAtIndexPath but not didSelectRowAtIndexPath. I believe the latter is called as a result of the former. If your delegate deSelects the last selected index path in didSelectRowAtIndexPath, then the double call would result in deselecting what you had just selected

seems like the issue was because I was calling the code from viewDidLoad, I moved it to viewDidAppear and now its fine

Related

Custom UITableViewCell is nil

I am using xib to load the cell in the UITableViewController. There is a button on the cell by hitting which a modal pops up and when we hit something on that modal, I want to change the image in the cell. But I am not able to get the cell even if I am passing the indexPath.
I have used following code:
NSIndexPath* indexPath1 = [NSIndexPath indexPathForRow:sender inSection:0];
[self.tableView2 reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath1, nil] withRowAnimation:UITableViewRowAnimationNone];
I have written the code in the cellForRowAtIndexPath as follows:
if([[feedbackDictionary objectForKey:[NSString stringWithFormat:#"Key%li",indexPath.row]] isEqualToString:[NSString stringWithFormat:#"%li",indexPath.row]])
{
NSLog(#"Yay! Feedback");
cell.checkmark.image=[UIImage imageNamed:#"tick"];
}
else
{
NSLog(#"Oops! No feedback");
cell.checkmark.image=[UIImage imageNamed:#"orangetick"];
}
I am supposing that when reloadrows will run,it will reload that particular cell by calling cellForRowAtIndexPath. But it is of no help. The image is not changing at all.
Secondly, I tried to get the cell by using following
NSIndexPath *ip=[NSIndexPath indexPathForItem:button.tag inSection:0];
ExpandingCell *cell=(ExpandingCell*) [_tableView2 cellForRowAtIndexPath:ip];
if(cell==nil)
{
NSLog(#"No cell");
}
I am getting no cell as output. Please help.
At first, to debug it try to call [self.tableView2 reloadData]. If your image is changed, it means that you were called wrong indexPath for reloadRowsAtIndexPaths method.
Also button.tag could return wrong tag, because cells are reusable in UITableView, and it can be cell that already used before.
I have found the problem and fixed it. The problem was when modal pops up,it was loosing control over the view controller and that is why tableview is null and nothing was changed.

Programmatically select UITableView cell not in current view

So it's easy to select a row that is currently in the UITableView. For example, to select the first row:
[self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
animated:YES
scrollPosition:UITableViewScrollPositionNone];
Say that I have an array that is the data source for the table and the array count is greater than the number of cells displayed in the tableview. How can I get the UITableView to scroll to an index from the array that is beyond what is currently being displayed in the tableview?
All I am trying to do is to replicate programmatically what a user would do with their index finger as they scroll down the table.
My specific table displays 9 rows. My array has 20+ items. As the UIViewController loads, it retrieves the row number that should be selected (from an integer stored in NSUserDefaults). But I find that it will only scroll to the correct array position if that integer value is between 0 and 8. If it is 9 or greater, nothing happens, and I can't figure out how to make it respond to this. I've looked at all the UITableViewDelegate methods and none seems to address this.
What I've been doing to scroll and select a specific row is this (example arbitrarily selecting row 11):
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:11 inSection:0]
atScrollPosition:UITableViewScrollPositionTop
animated:YES];
[self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:11 inSection:0]
animated:YES
scrollPosition:UITableViewScrollPositionTop];
Can anyone help me? I assume it isn't difficult, but I'm stuck.
Thanks!
Your cells that are off the screen ain't selecting because you are using reusable cells. The cells from the visible screen will be used later, it isn't that all 100 cells are cached and each cell is responsible for each row. What it means is that they could or couldn't have something in it already. For example, lets say you have cell for row 1. When it comes off the screen, in the next few cells it will be reused as cell 15 or something, and if it had selected properties, it will still have it. It is like a new job and you get a desk from the developer before you - you could have desk with his trash, but it could also be clean.
I wouldn't select them as you select them by method, but in if statement in your cellForRowAtIndexPath. Something along the lines (added comments):
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
// When using method with forIndexPath you don't have to check for nil because you will always get cell
MyTableCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
MyObj *obj = [self.myArray objectAtIndex:indexPath.row];
cell.location.text = obj.location.location_description;
// other formatting, text display, image loading, etc.
if ([self.selectedObjects containsObject:obj]) {
// do some selecting stuff
} else {
// but don't forget to unselect because you can get already selected cell
}
return cell;
}
Edit: To select invisible cell, first scroll to it, then select:
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
[self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionTop];
Try using UITableViewScrollPositionBottom instead of UITableViewScrollPositionNone
That is use this code
[self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:10 inSection:0]
animated:YES
scrollPosition:UITableViewScrollPositionBottom];
I figured this out. My code was running in viewDidLoad which is too early. I needed to move it to viewDidAppear. At least I know that I am not losing my mind.

Use an IBAction to select and press a table cell row

I am trying desperately to make this IBAction just effectively press a cell at a selected row. I have managed to get it to select a row, but I can't work out how to effectively click on this cell! I am only making my first app but I have managed to figure most things out by myself, but just can't seem to find out how to do this, i'm hoping it is a simple solution (or there is a much better way to do it than I have).
Here is the code for my IBAction anyway:
- (IBAction)myButton:(id)sender {
// Specify which cell I wan't to select
NSIndexPath *myIP = [NSIndexPath indexPathForRow:0 inSection:0];
// Select it
[self.tableView selectRowAtIndexPath:myIP animated:NO scrollPosition:UITableViewScrollPositionTop];
// Click this cell??
}
Thanks in advance for any help
Just tell the delegate that you've selected it
[self tableView:self.tableView didSelectRowAtIndexPath:myIP];
Assuming that self is your VC that controls the table.
The below stackoverflow answer looks like exactly what you need...
Automatically cell selected UITableView
Not a clean way to achieve but as per my understanding, You can add custom UIButton (transparent) on each cell such a way it covers almost complete cell in cellForRowAtIndexPath:, disable row selection. On these button you can use addTarget:action:
If your view controller that has the UITableView in it, is not subclassing UITableViewController you need to create an IBOutlet of the UITableView call it myTableView or whatever you'd like, then in your IBAction you can reference it like this:
- (IBAction)myButton:(id)sender {
// Specify which cell I wan't to select
NSIndexPath *myIP = [NSIndexPath indexPathForRow:0 inSection:0];
// Select it
[self.myTableView selectRowAtIndexPath:myIP animated:NO scrollPosition:UITableViewScrollPositionTop];
// (Per Dmitry's answer)
[self.myTableView didSelectRowAtIndexPath:myIP];
}

cannot select UITableViewCell programmatically

I am attempting to select, in the view did appear method, a table cell programatically.
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:1 inSection:1];
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
my delegate,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
does not get called.
The delegate gets called if i select the cells in the simulator with a mouse, however, just not programmatically.
Why can this be?
Because that's how the framework works. Try reading the docs. That's what they are for!
selectRowAtIndexPath:animated:scrollPosition:
Selects a row in the receiver identified by index path, optionally scrolling the row to a location in the receiver... Calling this method does not cause the delegate to receive a tableView:willSelectRowAtIndexPath: or tableView:didSelectRowAtIndexPath: message.
That's pretty easy to understand. The delegate method didSelectRowAtIndexPath: is not called if you select the row in code (programmatically). It is called only if the user selects the row.
And this makes perfect sense, because:
If you are selecting the row in code, you might not want the delegate method triggered.
If you do want the delegate method triggered, since you are in your own code, you can just call it.
You don't need the delegate method in order to learn that the row was selected, because you selected it in code - you cannot not know!

How to make a UITable to highlight its 5th row when we start the app?

I am using a splitviewcontroller. When I select something in the table the row is highlighted and it is shown in the detailed view. I have also provided an option to change the contents in the detailed view by scrolling.
When I start I want the the 5th row to be highlighted by itself, how can I do it?
Check out the following UITableView method:
- (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;
I was using the above function from the start. But the app was crashing when I wrote this code into the viewDidLoad.
NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:5 inSection:0];
[self.tableView scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
There is no data loaded into the UITableView instance. You can't select a row that doesn't exist. This was the reason it was crashing. And yes, this is the function that will help us do it.

Resources