Iglistkit: ItemAtIndex methods always return index 0

Created on 30 Mar 2017  路  9Comments  路  Source: Instagram/IGListKit

New issue checklist

General information

  • IGListKit version: 2.0.0
  • iOS version(s): 10.2.1, 10.2
  • Xcode version: 7.3.1
  • Reproducible in the demo project? (Yes/No): Yes

I created an extension for my section controller
extension MySectionController: IGListSectionType

Each time one of the following methods is called:
cellForItemAtIndex
sizeForItemAtIndex
didSelectItemAtIndex

the index value past to the function is always 0.

On didSelectItemAtIndex I am changing the cell state and calling
collectionContext?.reloadSectionController(self) but again the index is 0. The cell updates the way I want but without the correct index I can't update the rest of the cells.

question

Most helpful comment

@jonauz does your section controller only contain a single cell (what are you returning in numberOfItems())? If so, the index parameter in didSelectItem(at index:) will always be 0 b/c there is only one cell. Remember that the index is relative to the cells within that section.

If you want to respond to individual cell taps at the list-level, you can attach a collectionViewDelegate onto your adapter and respond to changes. indexPath.section will map to the object that was selected, e.g. adapter.objects[indexPath.section].

All 9 comments

The index is the index of some item in the section controller.

I guess you need [self.collectionContext sectionForSectionController:self], which is the index of the section in the collectionview.

So how can I change a cell at a specific index when didSelectItemAtIndex is called and update the other cells? I want to compare the current index to the other cells indexes

It depends on how you implement the section controller.

If the section controller has several cells, and what you want is to update some cell in the same section controller, just use IGListCollectionContext to do what you want.

But if you want to interact with some cell outside the section controller, maybe you have to notify your action outside the section controller

@PhilCai1993 I am trying to interact with cells inside my section controller. But when I reload a section at a specific index the index is always 0.
When a cell is selected I am reloading it with a new cell. If another cell is selected I want to reload it as well and return the previous cell to the original state, but I can't access the previous cell by passing the index. Is there a way to reload the whole section? and also is there a way to change the cells by passing the index inside the section controller?

Thanks for your comments so far.

@PhilCai1993 also, I am notifying my view controller that the cell is selected and passing the index like this : let section: NSInteger = (self.collectionContext?.sectionForSectionController(self))!
and then NSNotificationCenter.defaultCenter().postNotificationName("updateList", object: section)
But I can't figure out how to update the specific cell from my view controller.

Hi, Don't understand how come this questions is closed, when issue don't seem to be solved.
I just came across of the same issue, and I noticed that none of examples is using index in didSelectItem(at index: Int) function.
I followed all possible implementations and this function seems to have some logic issue or a bug.
I need index to identify which cell was selected in horizontal embedded collection view. But index is always 0, and examples don't use and don't show how to access this index.
Normally in our code we always use this parameter to identify which data we should use from the data source.
Please, could you explain how to access index or the selected object related with selected cell?
And also, what is the use of index if it's always 0. Does seem like a bug. Maybe was missed as other use some other ways for such implementation.
Please share some more knowledge on this.

@jonauz does your section controller only contain a single cell (what are you returning in numberOfItems())? If so, the index parameter in didSelectItem(at index:) will always be 0 b/c there is only one cell. Remember that the index is relative to the cells within that section.

If you want to respond to individual cell taps at the list-level, you can attach a collectionViewDelegate onto your adapter and respond to changes. indexPath.section will map to the object that was selected, e.g. adapter.objects[indexPath.section].

I understood more while was trying to explain my architecture and now see where is my mistake. Thank you @rnystrom , your answer helped a lot. Wish documentation would be a bit more clear on these steps, especially as I'm just starting with IGListKit, and had to spin my head around to understand logic of all flow. Plus spent a lot of time with examples and code, as documentation has differences between stable 2.1.0 and master versions. Seams steep learning curve for confident use.

Here is my implementation for the sake of clarity and hopefully useful tip for some:
In ViewController page I return many types of section controllers for each section object.

One of section controller is almost identical copy of HorizontalSectionController from examples, which contains adapter inside.
In there numberOfItems() returns two: 1 - title cell; 2 - cell with embedded horizontal collection view.
2nd cell is using EmbeddedCollectionViewCell and EmbeddedSectionController implementation approach from examples. Even using adapter.collectionView = cell.collectionView in cellForItem(...), just to be more specific (though, "why cell contains collection but adapter is out side of cell?" is not entirely clear).

I'm returning multiple objects in objects(for:)->[IGListDiffable] and using EmbeddedSectionController in listAdapter(_:sectionControllerFor:)->IGListSectionController.

And here is the part where I tried to use didSelectItem(at index: Int), but now I get that embedded horizontal collection view cell is also made of section controllers, which contains only single cell.
So now it's clear why this methods returns always 0.

Conclusion:
There is no example which shows how to use adapter.collectionViewDelegate = self with collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath).

@jonauz fantastic feedback! Glad you got it working. I filed a new issue to add some documentation to make it a little easier to understand.

Was this page helpful?
0 / 5 - 0 ratings