UITableView Detect Selected Cell? - iphone

I have multiple UITableViews in my app, is there a method of detecting which cell/row the user has selected in that column?
Also is it possible to programatically deselect a cell/row?
Thanks.

Get currently selected index path for a table:
NSIndexPath *path = [tableView indexPathForSelectedRow];
Deselect currently selected row:
[tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:YES];

These are all easily found in the documentation for UITableView. Perhaps you should look there first next time.
Here's even a link: http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableView_Class/Reference/Reference.html

NSIndexPath *path = [tableView indexPathForSelectedRow];
The above line will throw EXC BAD ACCESS if no sell is selected so keep track of your selected cell with NSIndexPath instance variable and only deselect when it is actually selected with isSelected property of cell.
UITableViewCell *cell = [tableView cellForRowAtIndexPath:someIndexPath];
if(cell.isSelected) {
[tableView deselectRowAtIndexPath:someIndexPath animated:YES];
}

Related

Where to use scrollToRowAtIndexPath in iphone?

I am using [self.messageList scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO]; in cellForRowAtIndexPath and it is working fine, when a row is added in table array then it auto scroll upside but the problem is that when I try to see the top rows then it automatically come again last rows. And I am not able to see my all rows. Please let me know where I use this or any other approach to do this.
cellForRowAtIndexPath method is not called for all cell that you have. It is only called for visible cell in your TableView. When You Scroll UITableView then it ask to UITableView that you want to use reusable cell or add to new one. generally we use reusable cell so, it is use 1st no of cell and add at end of cell . it is not create another new cell at the end. so, when you scroll your UITableView it not scroll to end of cell it indexPath is similar to indexPath of first no of cell. so you can not scroll your UITableView at to Down.
use following code may be helpful for you.... :)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"S%1dR%1d",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
[self.tblView scrollToRowAtIndexPath:indexPath atScrollPosition: UITableViewScrollPositionTop animated: YES];
// your code
}
// your code
return cell;
}
If you write this code in your cell for row at index path, then it will get called every time you try to scroll manually coz this message is called to draw your cell and you will b directed to the row you specified. Try checking your indexpath in a IF--Else block and scroll only when a certain action happens.
cellForRowAtIndexPath is a method for creating a cell to view .When you scroll this method is called when a cell is viewed.So each time the method called the [self.messageList scrollToRowAtIndexPath:indexPath method(which is called inside cellForRow) is also called and the table scrolls down to that row!!!

Reload specific UITableView cell in iOS

I have a UITableView. I want to update the table data based on selection made. Right now I use [mytable reloadData]; I want to know if there is any way where I can just update the particular cell which is selected. Can I modify by using NSIndexPath or others? Any suggestions?
Thanks.
For iOS 3.0 and above, you just have to call :
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
To reload row 3 of section 2 and row 4 of section 3 for example, you'll have to do this :
// Build the two index paths
NSIndexPath* indexPath1 = [NSIndexPath indexPathForRow:3 inSection:2];
NSIndexPath* indexPath2 = [NSIndexPath indexPathForRow:4 inSection:3];
// Add them in an index path array
NSArray* indexArray = [NSArray arrayWithObjects:indexPath1, indexPath2, nil];
// Launch reload for the two index path
[self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationFade];
You can also get a reference to the UITableViewCell object and change its labels, etc.
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.text = #"Hey, I've changed!";
I think you're looking for this method of UITableView:
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation

Deselecting a row in table view does not animate

I have a view controller that manages a table view. My understanding is that a table cell will be deselected automatically if I push another viewcontroller and then pop back to the table view.
However, in the same class (that I use a few times), there is one instance of the class when the cell is deselected but not animated (it'll just turn blue and then back to normal without animating). Why did this happen? I have a few instances of this class but it only happens to one of them. What might be causing this?
From my experience cells are not automatically deselected if you push/pop a view controller (at least not when using a navigationcontroller), unless you add some code te deselect it !
It may also be automatically deselected if you are doing a [tableView reloadData] in viewWill/DidAppear (or in a process started in these methods).
Did you try to add something like that in viewDidAppear ?
NSIndexPath *indexPath = [tableView indexPathForSelectedRow];
if (indexPath != nil) {
[tableView deselectRowAtIndexPath:indexPath animated:YES]
}
NSIndexPath *indexPath = [tableView indexPathForSelectedRow];
if (indexPath != nil) {
[tableView deselectRowAtIndexPath:indexPath animated:YES]
}
this you have to write in didselectRowAtIndexPath method
You can reload the Tableview again.
In your viewWillAppear
[yourTableView reloadData];
Or if you dont want to disturb your Datasource try this
NSArray *array = [yourTableView visibleCells];
for(UITableViewCell *cell in array)
{
cell.selected = NO;
}

I want to add check sign in row when any row is selected in UITableView

I want to add a check sign when any row is selected in table view please help
Implement tableView:didSelectRowAtIndexPath: in your table view delegate, grab the cell that was selected using [tableView cellForRowAtIndexPath:indexPath] and set its accessory to UITableViewCellAccessoryCheckmark.
If you want to implement something similar to the multi-value table views in the Settings app, what I do is use a property to keep track of what's already selected:
#property (nonatomic, retain) NSIndexPath *selectedIndexPath;
In the same delegate method, I remove the checkmark from the cell at the selection, add the checkmark to the cell that was tapped and update the property with the index of that cell:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:self.selectedIndexPath];
[oldCell setAccessory:UITableViewCellAccessoryNone];
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
[newCell setAccessory:UITableViewCellAccessoryCheckmark];
[self setSelectedIndexPath:indexPath];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
To go one step further, you can find a way to persist the index path in your app (possibly using NSUserDefaults, and in tableView:cellForRowAtIndexPath: apply the checkmark to whichever cell that corresponds to that index path, so your checkmark shows up on view load.
http://iphonedevelopment.blogspot.com/2008/10/table-view-multi-row-edit-mode.html

How do you change the textLabel when UITableViewCell is selected?

I want to change the textLabel and detailTextLabel of a cell when it has been selected.
I've tried the following, but no change occurs:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MyAppDelegate *appDelegate = (MyPhoneAppDelegate*)[[UIApplication sharedApplication] delegate];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.detailTextLabel.text = #"xxxxx";
cell.textLabel.text = #"zzzzz";
[tableView reloadData];
}
I agree, reloading the table view will actually dump and reload/display all the cells using tableView:cellForRowAtIndexPath: and use the original data, not the updated #"xxxxx" and #"yyyyy" in your tableView:didSelectRowAtIndexPath: method.
In a little test project I was able to change the labels upon selection with:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.text = #"it was tapped";
}
You should not be trying to reload the table while a cell is selected. Instead, try
[cell setNeedsLayout]
after you make the above changes to the labels.
Also, is there a reason you're making a reference to the app delegate in the method?
Try to reload the cell you selected (described by indexPath) :
[yourTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
Create a New iPad Project (Split View) and Now go through the Classes->Files. The easiest way's been given there. The XCode's Generated Codes.
Sample Code Lines :-
cell.textLabel.text = [NSString stringWithFormat:#"Row %d", indexPath.row];
You can use them in cellForRowAtIndexPath ||&& didSelectRowAtIndexPath ..
Not sure what you're trying to do with the delegate but you should try calling the tableView already instantiated; i.e. call
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath: indexPath];
Maybe I'm not clear
What I'm saying is that you are instantiating a new empty table view
UITableViewCell *cell = [**tableView** cellForRowAtIndexPath: indexPath]; //cell has nothing it is new.
consider replacing to call the old
UITableViewCell *cell = [**self.tableView** cellForRowAtIndexPath: indexPath]; //now you have one that has a textField already in it
Did you try to refresh only the selected cell instead of reloading the whole table ?
[cell setNeedsDisplay];
instead of
[tableView reloadData];
This will have better performance and I'm not but I suppose that selection is lost if you refresh the whole table (this may be the reason why you don't see any change in the end)....