1

Here's the background: I have a UICollectionView which contains UITableView as its cell. Whenever I select UITableViewCell, I want to know which UICollectionViewCell the action is from.

But I fail to get the right index of UICollectionViewCell. As the code below.

First, in the init method, I register my custom cell.

 [self registerClass:[QuestionCVCell class] forCellWithReuseIdentifier:QuestionCVCellIdentifier];

Then, in the UICollectionViewDataSource.

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell *cell = nil;
        cell = (QuestionCVCell *)[collectionView dequeueReusableCellWithReuseIdentifier:QuestionCVCellIdentifier forIndexPath:indexPath];
        if (_questions && _questions.count > 0) {
            ((QuestionCVCell *)cell).model = [_questions objectAtIndex:indexPath.item];
            ((QuestionCVCell *)cell).index = indexPath.item;

            NSLog(@"   %ld, %ld",(long)indexPath.item, (long)indexPath.row);
        }
       return cell;
}

The log is in mess, and not same as the right index I meant. I guess it has something to do with the dequeueReusableCellWithReuseIdentifier?

In code above, cell.index is passed to QuestionCVCell, which contains a tableview. I add a notification poster in its didSelectRowAtIndexPath: delegate to let main controller know that the select is from which collectionview cell.

This is the whole process of my problem.

I've searched for similar questions in Google, and find some solutions like these:

  • Get the index from delegate of UIScrollView;
  • Get the index by the point you touch, using indexPathForItemAtPoint: or similar methods.
  • Someone said that it should be indexPath.item in collectionview instead of indexPath.row, so I logged both of them and didn't see the difference.

So my question is:

  • Is there a direct way to get the correct index of UICollectionView? Why I get the right model by [_questions objectAtIndex:indexPath.item] but the wrong index by indexPath.item ?

  • Is there any better way to let main controller know that the tableview cell select action belong to which collectionview cell?

  • If you find any problem or mistake in my solution, please do let me know.

Thanks in advance if anyone could help with it.

Calios
  • 806
  • 9
  • 23
  • It isn't at all clear what you are asking or what your problem is. `indexPath.item` is the item for which the code shown needs to return a cell. Are you trying to use this information in `didSelectRowAtIndexPath` for your embedded table views? If so then show that code. – Paulw11 Dec 12 '15 at 03:05
  • @Paulw11 I'm sorry for the unclear description. In brief, my problem is that I can't get the right index of UICollectionView when I scroll it horizonally. And here's my [demo](https://github.com/caliosd/surveyquestionnaire). Thanks for your patience. :) – Calios Dec 12 '15 at 03:20
  • I still don't know what you mean by "right" - The indexPath.item that is provided to the code you have shown in the indexPath.item that is required for the cell returned by the code you have shown; it is inherently "right"; if you are referring to accessing the indexPath in some other function please show that code. – Paulw11 Dec 12 '15 at 03:30
  • @Paulw11 I've just updated my question. Please have a look. – Calios Dec 12 '15 at 03:40
  • I still don't understand *where* you are getting the wrong `indexPath.item` Which line of code? What value do you get? What value do you expect? – Paulw11 Dec 12 '15 at 03:52
  • @Paulw11 At the  log part. For example, when I scroll the collectionview from left to right and the other way round, I expect to get "0, 1, 2, 3, 4, 5, 4, 3, 2, 1", but I get some value like "0, 1, 2, 3, 4, 5, 3, 4, 2". – Calios Dec 12 '15 at 03:57
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/97695/discussion-between-paulw11-and-calios). – Paulw11 Dec 12 '15 at 03:58

3 Answers3

0

I give you sample collection view code.It helps you get the index.

in viewDidLoad

 UINib *cellNib = [UINib nibWithNibName:@"QuestionCVCell" bundle:nil];
 [collectionView registerNib:cellNib forCellWithReuseIdentifier:@"cvCell"];

in CollectionView Data Source Methods

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
 static NSString *cellIdentifier = @"cvCell";
 QuestionCVCell *cell = (QuestionCVCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
 //Here you need to give your QuestionCVCell data instead of my data;
 cell.img_Collection.image = [imgArray objectAtIndex:indexPath.row];
 cell.lbl_Collection.text = [lblArray objectAtIndex:indexPath.row];
 NSLog(@"The current indexPath row is - %ld",(long)indexPath.row);
 cell.tag = indexPath.row;
 return cell;
}

in Collection View Delegate method

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
  NSLog(@"The touched index path os collection cell item row is - %ld",(long)indexPath.row);
}
user3182143
  • 9,459
  • 3
  • 32
  • 39
0

instead of using indexPath.row use indexPath.item in UICollectionView. it will give you correct index.

NSIndexpath.item vs NSIndexpath.row

Community
  • 1
  • 1
Nitin Singh
  • 271
  • 2
  • 12
0

Use the delegate pattern to achieve this.

i) In CollectionView Data Source Methods set the cell tag as indexPath.row

 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    QuestionCVCell *cell = (QuestionCVCell *)[collectionView dequeueReusableCellWithReuseIdentifier:QuestionCVCellIdentifier forIndexPath:indexPath];

    if (_questions && _questions.count > 0) {
        cell.model = [_questions objectAtIndex:indexPath.item];
    }
    cell.delegate = self;
    cell.tag = indexPath.row;
    return cell;
}

ii) Create a custom delegate in QuestionCVCell class

@protocol QuestionCVCellDelagate <NSObject>
- (void)tableSelectedWithIndex:(NSUInteger)index;
@end

@interface QuestionCVCell : UICollectionViewCell
@property (nonatomic, weak) id<QuestionCVCellDelagate>delegate;
@end

iii) In tableView didSelectRowAtIndexPath method invoke the delegate method

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (self.delegate && [self.delegate respondsToSelector:@selector(tableSelectedWithIndex:)]) {
        [self.delegate tableSelectedWithIndex:self.tag];
    }
}

iii) Adopt the protocol in the ViewController class and add the delegate method.

- (void)tableSelectedWithIndex:(NSUInteger)index {
    //do whatever you with the index.
}

Now whenever the table row is selected, it calls the tableSelectedWithIndex method with collection view index in ViewController class

Surya Subenthiran
  • 2,217
  • 1
  • 15
  • 22