I have UIcollectionview with sections. In cellForItemAtIndexPath i can see indexPath.section and indexPath.item. How can i know number of the item from the very beginning of the first section?
There is no built-in method. But you can add the number of items of all previous
sections to the item number within the current section:
NSInteger num = indexPath.item;
for (NSInteger section = 0; section < indexPath.section; section++) {
num += [collectionView numberOfItemsInSection:section];
}
But perhaps you should also check if you really need this. For example, if the reason is
that your data source is a flat array then you might consider to rearrange the data source,
reflecting the two-level sections/items structure.
You need the cell at indexPath (0,0), so try:
NSIndexPath * indexPath = [NSIndexPath indexPathForItem: 0 inSection: 0];
and then use cellForItemAtIndexPath as before
You might be looking for indexPath.row.
Related
I can get the row number by indexPath.row in didSelectRowAtIndexPath, and different section are getting the same index like 0,1,2,3; 0,1; 0,1,2 ... How can I find out which section is being selected?
You can use NSIndexPath section property
indexPath.section
I have 6 sections in a UItableView, every section displays 2 cells, normally, I want it like this:
However, here is what I have:
Every indexPath.row is duplicated in every section.
Here is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"avenir";
Avenir *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(!cell) {
cell =[[Avenir alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.equipea.text=[arrayofClubA objectAtIndex:indexPath.section];
cell.equipeb.text=[arrayofClubB objectAtIndex:indexPath.section ];
return cell;
}
The elements are retrieved from two NSMutableArrays, one for the first left element in cell and the other for the right element cell.
What is wrong?
Thank you for helping.
You need to calculate the correct index from both the row and the column. Since you have two pairs of rows per section, you need to multiply section by two, and add row, which will be either zero or one. The end result should look like this:
NSUinteger pos = indexPath.section*2 + indexPath.row;
cell.equipea.text=[arrayofClubA objectAtIndex:pos];
cell.equipeb.text=[arrayofClubB objectAtIndex:pos];
You're always fetching the identical text for each section, since
cell.equipea.text=[arrayofClubA objectAtIndex:indexPath.section];
always returns the same value for each section (since indexPath.section contains the section's index). Perhaps you wanted to do to the following instead?
cell.equipea.text=[arrayofClubA objectAtIndex:indexPath.row];
Also, for these kind of uses, it might be a lot more straight forward to use the free Sensible TableView framework as it automatically handles displaying your arrays.
I have one custom cell in a table with one textfield (cell.guestName.text), users add more rows depending on how many guests they have. I am struggling with fetching the guest name entered in each guest field.
Can anyone help me do this please?
Thanks in advance.
Use an NSMutableArray to keep track of the Guest Names for each row in the TableView. Then it is just a matter of adding to that array each time a new row is added to the TV. Getting the value of all cells or just one cell is easy to with objectAtIndex or a for-in loop on the Array
You get the number of rows and sections (but probably you already know that number) with numberOfSections and numberOfRowsInSection.
Then you get all cells using cellForRowAtIndexPath passing all the possibile index paths, and you retrieve the text.
Example:
for(NSUInteger i=0; i< [self.tableView numberOfSections]; i++)
{
for(NSUInteger j=0; j<[self.tableView numberOfRowsInSection: i]; j++)
{
NSIndexPath* path= [NSIndexPath indexPathForItem: j inSection: i];
UITableViewCell* cell= [self.tableView cellForRowAtIndexPath: path];
// Do whatever with the cell
}
}
I have a table view which I'm using for some settings in my app. The tables cells are all default (no customisation at all), and simply contain some text for their label and a UISwitch for the accessory view.
My problem is that I need a reference to the switch so that I know when it has been switched on and off.
Currently I am setting the 'tag' property of the switch to be that of the cell's index within the table (grabbed from [indexPath row] in tableView:cellForRowAtIndexpath:).
This is fine when you only have one Section in your table, but I am now adding a new section. The problem is that they are both 0 based indexed so the switches in each section will end up reusing the tags - which isn't good.
Any suggestions on a better way to achieve this?
Thanks.
If you know roughly how many sections and rows you will have, like oh, say, not more than 1 million rows per section, just hash the section and row like this:
const int oneMillion = 1000000;
int tag = (section * oneMillion) + row;
slider.tag = tag;
Then, to figure out the section and row, reverse the logic:
int tag = slider.tag;
int row = tag % oneMillion;
int section = tag / oneMillion;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: row inSection: section];
Now get the slider that is in the cell in that section,row of the table
UITableViewCell *sliderCell = [tableView cellForRowAtIndexPath: indexPath];
UISlider *slider = [[sliderCell.contentView subviews] objectAtIndex: 0];
This assumes the slider is always the only view in the contents of the cell.
This method is a bit longer than some of the other suggestions above, but it keeps you from having to cache references off to the side.
For each cell, set a delegate link back to the table view controller, and also some kind of row reference ID - then wire the switch to a cell IBAction method, that calls back to the delegate with the reference ID for that cell.
What you can do is either have an Array of arrays or a dictionary, key it by the section number (or in case of the array they will be in order of the section numbers), now to retreive a switch all you do assuming you know the section and the row number
UISwitch *switch=[[switchArray objectAtIndex:section] objectAtIndex:row];
or if you have a dictionary
UISwitch *switch=[[switchDictionary objectForKey:section] objectAtIndex:row];
I have a UITableView with pagingEnabled. Each cell takes up the viewing area of the table. Meaning, each cell is the same height and width as the table. I'm using custom cells that have a name property. I'd like to display the name of the current (viewable) cell in a label. This works fine for the first and last cells but anything inbetween isn't so easy. The problem is that cellForRowAtIndexPath is called twice for these middle cells. Here's what it looks like scrolling from the first to last cell and then back. I've listed the indexes in order as cellForRowAtIndexPath fires for that row:
Row indexPath.row
0 0 //view loads and table appears
1 1,2 //user scrolls to second cell. cellForRowAtIndexPath fires twice. First time indexPath.row is one and second time it is two. This causes cell two's name to display in the label, rather than cell one.
2 2,3
3 3
//user starts scrolling back to first cell
2 1,2
1 1,0
0 0
I could set use an NSDate object to detect if I'm in a middle row. By diffing the previous time with current, I'll know. However, if the user scrolls really fast through the cells, that probably doesn't work. Is there another way to do it?
I've tried using variations of visiblecells properties but that didn't work. The UITableView will load the next cell even if it isn't visible, causing it to be part of the visible cells.
Well, on the off chance that you never figured out a solution, or for whoever comes to this question next, I'll provide you with the answer you were looking for. UITableView will provide you with the indexPaths you are looking for, and then UITableView will happily provide you with the cells that match those index paths:
UITableView *tableView = self.tableView; // Or however you get your table view
NSArray *paths = [tableView indexPathsForVisibleRows];
// For getting the cells themselves
NSMutableSet *visibleCells = [[NSMutableSet alloc] init];
for (NSIndexPath *path in paths) {
[visibleCells addObject:[tableView cellForRowAtIndexPath:path]];
}
// Now visibleCells contains all of the cells you care about.
Converted Douglas example to Swift:
let tableView = self.tableView // Or however you get your table view
let paths = tableView.indexPathsForVisibleRows
// For getting the cells themselves
let visibleCells : NSMutableSet = []
for path in paths! {
visibleCells.addObject(tableView.cellForRowAtIndexPath(path)!)
}
Rather than focusing on when the UITableView requests a cell, you should be focusing on when it displays the cell, which is indicated by the delegate method tableView:willDisplayCell:forRowAtIndexPath.
Simple and elegant way to retrieve visible cells of UITableView, no need to get visible cells by using indexpath values
NSArray * visibleCells = tableView.visibleCells;
NSLog(#"Total visible Cells: %i", [visibleCells count]);
If indexpath's of visible cells are needed
NSArray * paths = [tableView indexPathsForVisibleRows];
Swift 4+
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let firstVisibleIndexPath = self.tableView.indexPathsForVisibleRows?[0]
print("top visible cell section is \([firstVisibleIndexPath!.section])")
}