How to get indexPath from table view? - iphone

So in my app, which is based around UITableViews, I am getting the indexPath for the row for methods like didSelectRowAtIndexPath: like so:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger row = [indexPath row];
// Extract Data
CTCoreMessage *message = [[self allMessages] objectAtIndex:row];
}
My question is, what if I wanted to receive the indexPath in an IBAction? How would I do that since there is no NSIndexPath declaration in the header of the method?
Thanks!

But you don't really want the index path, you want the row, yes? You need to configure the sender (some UIControl) of the action to know your row.
Option 1: set the senders tag property (quick and simple).
Option 2: subclass the sender and add a property to store the row (technically correct).
Where you configure the sender depends on how and where you create it and how it relates to the table view, probably in -tableView:cellForRowAtIndexPath:.

I have solved the problem with this code, thank you to everyone that helped!
NSUInteger nSections = [self.messagesTable numberOfSections];
NSUInteger nRows = [self.messagesTable numberOfRowsInSection:nSections];
NSInteger lastSection = nSections - 1;
NSInteger lastRow = nRows - 1;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:lastRow inSection:lastSection];
Thanks again!

Related

How to know the section number on button click of Tableview cell in a UITableView? [duplicate]

This question already has answers here:
How to know the UITableview row number
(10 answers)
Closed 9 years ago.
I have a UITableView for which I have created a custom UITableViewCell. Each row in tableview has a button. I want to know the section number on click of a button, so that I would know that from which section button has been clicked. I have already tried few things found on stack but nothing is working.
UIButton *b = sender;
NSIndexPath *path = [NSIndexPath indexPathForRow:b.tag inSection:0];
NSLog(#"Row %d - Section : %d", path.row, path.section);
Don't know what you've tried, but i might do something like this. Doing some pseudocode from memory, here.
- (void)buttonClicked:(id)sender {
CGPoint buttonOrigin = [sender frame].origin;
// this converts the coordinate system of the origin from the button's superview to the table view's coordinate system.
CGPoint originInTableView = [self.tableView convertPoint:buttonOrigin fromView:[sender superview];
// gets the row corresponding to the converted point
NSIndexPath rowIndexPath = [self.tableView indexPathForRowAtPoint:originInTableView];
NSInteger section = [rowIndexPath section];
}
If I'm thinking clearly, this gives you flexibility in case the button's not directly inside the UITableView cell. Say, if you've nested inside some intermediary view.
Sadly, there doesn't seem to be an iOS equivalent of NSTableView's rowForView:
Create a handler for button click and add it in tableView:cellForRowAtIndexPath: method
- (void)buttonPressed:(UIButton *)button{
UITableViewCell *cell = button.superView.superView;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
//Now you have indexPath of the cell
//do your stuff here
}
When you create your custom UITableViewCell in cellForRowAtIndexPath you should pass it its section as a parameter. It could look like:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyIdentifier"];
if (!cell)
{
cell = [[[MyCustomCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MyIdentifier" section:indexPath.section] autorelease];
}
return cell;
}
Now your cell knows its section and you can use it when performing click method in MyCustomCell class
Try this,
First assign section as a tag to button also add target on button in cellForRowAtIndexPath method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
[cell.btnSample setTag:indexPath.section];
[cell.btnSample addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
...
}
Get Section as tag from sender of IBAction you defined (buttonClicked here).
-(IBAction)buttonClicked:(id)sender
{
NSLog(#"Section: %d",[sender tag]);
}

How to get a UITableViewCell's subtitle show how many times that specific cell was tapped?

I have a uitableview that displays the values of an array. I would like to know if there is a way to update the subtitle of its table cells, based on how many times each cell was tapped.
Thank you!
First of all, you'll want to use a NSMutableArray so you can change its contents after instantiation. Here's a basic over view of what I just tried to achieve your intended results:
In your interface
#property (strong, nonatomic) NSMutableArray *tapCountArray;
In your implementation
- (void)viewDidLoad
{
[super viewDidLoad];
self.tapCountArray = [NSMutableArray new];
int numberOfRows = 20;
for (int i = 0; i < numberOfRows; i ++) {
[self.tapCountArray addObject:#(0)];
}
}
Then the important part!
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.tapCountArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSString *text = [self.tapCountArray[indexPath.row] stringValue];
[cell.textLabel setText:text];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tapCountArray replaceObjectAtIndex:indexPath.row withObject:#([self.tapCountArray[indexPath.row] intValue] + 1)];
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
When each cell is tapped the number in its detailTextLabel will be incremented up by one.
You shouldn't create a new array or set, that could lead to problems if the two arrays get out of sync with each other. The way to do it, as you suggested in your comment, is to use dictionaries. The way you said you were doing that is probably not the way, however. You want an array of dictionaries where the values for one key would be whatever your main data is and the value for the other key would be the number of taps. For example, lets call the two keys main and sub, and your main data is a set of names. The array of dictionaries would look like this: ({main:#"Tom",sub:1}, {main:#"Dick", sub:0}, {main:#"Harry",sub:2}, .....). In the tableView:cellForRowAtIndexPath:indexPath method you would provide the data to the cells like this:
cell.textLabel.text = [[array objectAtIndex:indexPath.row] valueForKey:#"main"];
cell.detailTextLabel.text = [[array objectAtIndex:indexPath.row] valueForKey:#"sub"];
I think you can just set up another array of the same length as the one you have now. Then when your didSelectRowAtIndexPath is triggered, increment your indexPath.row entry of the new array and refresh that cell. If you don't expect to shuffle the table, you don't need a dictionary.
You can insert the object into an NSCountedSet, and on your cellForRowAtIndexPath method, you would take the model object for the cell and verify the number of times it has been inserted into the NSCountedSet instance.
Take a look at the NSCountedSet documentation: https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSCountedSet_Class/Reference/Reference.html

How to hide custom check mark in table view

I have a UITableiew that I want to be able to display a custom check mark when the row is selected (tapped), however, if there is a check mark on any of the other rows, it must be hidden. What is the best way to do this? The IF... doesn't seem to work at all, it will not hide and unhide the check mark as I thought it would.
Thanks in advance.
-PaulS.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
home_2_CustomCell *cell = (home_2_CustomCell*)[tableView cellForRowAtIndexPath:indexPath];
//This will hide the selected row...
cell.imageViewDidSelectRow.hidden = YES;
// if (cell.imageViewDidSelectRow.hidden = NO){
// cell.imageViewDidSelectRow.hidden = YES;
// }
}
1) Maintain a tag in class level as an NSIndexPath variable.
2) Whenever a cell is selected make note of the indexPath and reload the table view.
3) In cellForRowAtIndexPath delegate check for this variable and set marks accordingly.
4) This will not be costly if you have the cell with less information.
You can get the each cell of tableview by this code
UITableViewCell *cell=[product_table cellForRowAtIndexPath:[NSIndexPath indexPathForRow:clickedTag inSection:0]];
make one for loop.
for(int i=0;i<[tabledata count];i++){
cell.imageViewDidSelectRow.hidden = YES;
}
for each cell except the current row which is selected and you got only one image displayed for the current row.

Referencing a UITableViewCell that gets created in cellForRowAtIndexPath

I have a button on my TableView header that is an empty box, and when pressed, is a checkmark. I have that same button on the cells for that header. So I basically want to perform an action on each cell that is in that section. I'm using the Animating TableView from WWDC 2010 as my example. The header object has an array of integers that keep track of how many rows are in its section.
I'm not really sure from here, how I can get the custom UITableViewCell to perform my action on. Any thoughts? Thanks.
So far I have something like this:
- (void)selectAllCheckmarksInSectionHeaderView:(SectionHeaderView *)sectionHeaderView forSection:(NSInteger)section {
SectionInfo *sectionInfo = [self.SectionInfoArray objectAtIndex:section];
int totalRows = [[sectionInfo rowHeights] count];
for (int row = 0; row < totalRows; row++) {
NSIndexPath *path = [NSIndexPath indexPathForRow:(NSUInteger)row inSection:section];
OrderTableViewCell *cell = (OrderTableViewCell *)[_orderTableView cellForRowAtIndexPath:path];
cell.CheckmarkButton.selected = YES;
}
}
However my OrderTableViewCell is nil.
To reference a button that is a located in a section header, you'll have to assign it to an instance variable to keep a reference to it. To obtain references to all of the cells in a section and update them, you'll want to try something like this...
CGRect sectionRect = [self.tableView rectForSection:0]; // Rect for first section
NSArray *indexPathsInSection = [self.tableView indexPathsForRowsInRect:sectionRect];
for (NSIndexPath *indexPath in indexPathsInSection)
{
// Obtain the cell at each index path and update its accessory state
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
Of course this is an overly simplistic example. A more flexible approach would be to update some model object when a section is "selected" and reload the table. Then in your -tableView:cellForRowAtIndexPath: you would determine whether a cell in a section should be checkmarked based off the model object for the whole section.

UITableView - get list of UITableViewCells in an indexPath.section

Is there a way I can iterate over a list of UITableViewCells contained in an indexPath.section?
Thanks
You can use UITableView's cellForRowAtIndexPath: to get a cell at a specific index. But this will only return a cell if it is currently visible in the table.
What are you really trying to do? Why do you need all cells in a section?
It's long ago that this question was asked but this might help other people searching for a solution.
NSInteger mySectionIdentifier = 0;
NSArray *visibleCells = self.tableView.visibleCells;
NSMutableArray *sectionCells = [NSMutableArray arrayWithCapacity:visibleCells.count];
for (UITableViewCell *cell in visibleCells) {
NSIndexPath *cellIndexPath = [self.tableView indexPathForCell:cell];
if (cellIndexPath.section == mySectionIdentifier) {
[sectionCells addObject:cell];
}
}
As you see this only works for visible cells but it would be easy to change the code to retrieve all cells instead of the visible ones.