0

I have a tableview that always shows 3 cells for each page.

I need to know if the selected cell is the first, the second or the third of the page.

I'm sure there's a formula to calculate that, but I'm not able to find it.

Edit: let's see if I can make myself clearer.

Imagine to have an array of 8 objects to show in a tableview. Because the tableview is paged, the first page will show the indexes 0, 1, 2 of the array, the second page will show the indexes 3, 4, 5, and the last page will show the indexes 6 and 7.

Let's imagine we're on the second page (indexes 3, 4 and 5 shown) and I select the second cell (index 4).

I need to know that the user has selected the second cell, and not the indexPath.row that in this case is 4.

Aleph72
  • 857
  • 1
  • 13
  • 35
  • Does this answer your question? [Get Selected index of UITableView](https://stackoverflow.com/questions/4030811/get-selected-index-of-uitableview) – bbarnhart Jan 14 '20 at 15:20
  • Nope. I already know the indexPath for the selected cell, I need a formula that gives me a 1, a 2 or a 3, based on what cell is selected in the page shown. – Aleph72 Jan 14 '20 at 15:22
  • What do you mean by page? – bbarnhart Jan 14 '20 at 15:24
  • I mean that the paging option for the scrolling is enabled and the table always shows 3 cells for scroll. – Aleph72 Jan 14 '20 at 15:28
  • How is there only 3 cells visible and is it always fixed triplets ie [0,1,2] or [3,4,5]? Would the visible cell ever be [1,2,3]? – bbarnhart Jan 14 '20 at 15:38

2 Answers2

1

You just have to apply the modulo operator:

let indexOnThePage = indexPath.row % 3

indexOnThePage will be 0 for the first, 1 for the second, and 2 for the third.

4 % 3 == 1 // That means the second cell of the page

Bonus: If you want the page number, just do:

let pageNumber = indexPath.row / 3

It'll give 0 on the first page, 1 on the second, and so on.

EDIT: Here is the the version with you last page problem.

func indexOnPage(row: Int, page: Int, total: Int, itemsOnPage: Int = 3) -> Int {
    let lastPage = total / itemsOnPage

    if page != lastPage {
        return row % itemsOnPage
    }
    else {
        let delta = total % itemsOnPage
        return (row - delta) % itemsOnPage
    }
}

indexOnPage(row: 0, page: 0, total: 5) // 0
indexOnPage(row: 1, page: 0, total: 5) // 1
indexOnPage(row: 2, page: 0, total: 5) // 2
indexOnPage(row: 2, page: 1, total: 5) // 0
indexOnPage(row: 3, page: 1, total: 5) // 1
indexOnPage(row: 4, page: 1, total: 5) // 2

This should work for your problem.

Zaphod
  • 5,766
  • 2
  • 33
  • 52
  • That's it! I knew it was easy, but I couldn't find it... it must be my flu :) – Aleph72 Jan 14 '20 at 15:51
  • Flu never helps! – Zaphod Jan 14 '20 at 15:58
  • I've already selected this answer, but I've seen now that it does not work in every case. For example, if the array has 5 entries, the first page will have the indexes 0, 1, 2, but the second page will have the indexes 2,3,4 and here is when it stops working well. – Aleph72 Jan 15 '20 at 07:45
  • The problem I see is that you ave the row with the id 2, is the third on the first page and first ont the second page. When you give the `indexPath.row` do you know the page ans the total count? – Zaphod Jan 15 '20 at 08:10
  • Yes, I know the total count and the page number. – Aleph72 Jan 15 '20 at 08:16
  • Ok, I edited the answer with a function doing what you want... I hope... – Zaphod Jan 15 '20 at 08:27
  • Not yet. The page count is not correct because the index 2 is on the first page at the beginning, but once scrolled the tableview, it ends up on the second page. So I don't know exactly how to know what page I'm in. – Aleph72 Jan 15 '20 at 08:44
  • Maybe you'll have simply to check what is the first visible row on your page. Check this out : https://developer.apple.com/documentation/uikit/uitableview/1614885-indexpathsforvisiblerows – Zaphod Jan 15 '20 at 08:53
  • Ok, I've finally made it work. I'm going to post the final solution, it may be useful to other users. – Aleph72 Jan 15 '20 at 10:14
0

This is what I came up with. Many thanks to @Zaphod for the help.

Here I'm getting the indexPaths for the visible cells:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSArray *visibleCells = [[NSArray alloc] initWithArray:[_tableView indexPathsForVisibleRows]];
    NSLog(@"Cell n. %d", [self indexOnPage:(int)indexPath.row idx:(NSArray*)visibleCells total:(int)[_licenses count] itemsOnPage:3]);
}

Then, to check if I'm on the last page, I've changed a little @Zaphod's solution to check if the last object is being shown:

-(int)indexOnPage: (int)row idx:(NSArray*)idx total:(int)total itemsOnPage:(int)itemsOnPage {
    NSIndexPath *lastIdx = [idx lastObject];
    int lastRow = (int)lastIdx.row;
    if (lastRow != [_licenses count]-1) {
        _selectedCell = row % itemsOnPage;
        return row % itemsOnPage;
    } else {
        int delta = total % itemsOnPage;
        _selectedCell = (row - delta) % itemsOnPage;
        return (row - delta) % itemsOnPage;
    }
}

Finally this method always returns 0 if the first visible cell is selected, 1 if the second cell is selected and 2 if the third cell is selected.

Aleph72
  • 857
  • 1
  • 13
  • 35