0

Goal:

Set up two collectionViews with different styles. One grid style and other single file style. These collectionViews will be toggleable giving users shopping within the ability to view the items for sale in which ever style (grid/single file) they prefer.

I have an existing collectionView with a custom cell set up in interface builder and it's working fine. I've tried to find info on how to add a second one via interface builder but have had no luck in finding any.

What I've done: I've created the second collectionView programatically in my viewDidLoad method. I have an instance variable named _collectionView2.

- (void)viewDidLoad
{
    [super viewDidLoad];

    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    _collectionView2 = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
    [_collectionView2 setDataSource:self];
    [_collectionView2 setDelegate:self];

    [_collectionView2 registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];
    [_collectionView2 setBackgroundColor:[UIColor redColor]];

    [self.view addSubview:_collectionView2];
    [_collectionView2 setHidden:YES];

I've modified delegate and datasource methods to make them aware about the new collectionView:

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    if (collectionView == _collectionView) {
      NSArray *people = [_thisController objects];
      return [people count];
    } else {

        return 20;
    }
}

.

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{      
    if (collectionView == _collectionView) {
         static NSString *CellIdentifier = @"Cell";
        VAGGarmentCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier: CellIdentifier forIndexPath:indexPath];

        [[cell activityIndicator] startAnimating];

        PFFile *userImageFile = [object valueForKey:@"image"];
        [[cell imageView] setFile: userImageFile];
        [[cell imageView] loadInBackground];

        [[cell activityIndicator] stopAnimating];

        [[cell title] setText:[object valueForKey:@"title"]];
        [[cell price] setText:[NSString stringWithFormat: @"£%@ GBP", [object valueForKey:@"price"]]];
        return cell;
    } else  {
         static NSString *CellIdentifier = @"Cell";

        UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];

        cell.backgroundColor = [UIColor greenColor];

        return cell;
    }

    //_addToFavouritesButton = [cell addFavouriteButton];

    [_addToFavouritesButton addTarget:_thisController action:@selector(addToFavouritesButtonTapped:) forControlEvents:UIControlEventTouchUpInside];

 }

.

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    if (collectionView == _collectionView2) {

      return CGSizeMake(50, 50);

    } else {
        return CGSizeMake(140, 272);
    }
}

Then I have a method that responds to the UISegmentControl being switched from grid style display to single file display:

- (void)displayTypeSegmentSelected
{
    _selectedDisplayTypeIndex = [_displayTypeControl selectedSegmentIndex];

    if (_selectedDisplayTypeIndex == 0) {
        NSLog(@"Single file item view selected");

        [_collectionView setHidden:YES];

        [_collectionView2 setHidden:NO];
    } else {
        NSLog(@"Grid style view selected");
        [_collectionView setHidden:NO];
        [_collectionView2 setHidden:YES];
    }
}

CollectionView2 is hidden initially then unhidden when the segment control is used. It looks like it's working because when I toggle a red background shows and I did set a red background when I created the collectionView but green cells aren't showing at all.

I can't seem to see where I've gone wrong. I'd like to get this working so I can replace the cell with my custom cell. The only difference between grid display and single file display is that single file display will be an enlarge cell that takes up the width of the view. All properties etc will be the exact same meaning I can use my current custom cell.

Why aren't my cells showing? I've followed a clear tutorial on creating a collectionView programmatically but still no cells are showing.

Update:

I put a log message in the if statement that checks what collectionView is present and it is only ever trigger for my _collectionView and not _collectionView2.

Help is appreciated.

Regards

LondonGuy
  • 10,778
  • 11
  • 79
  • 151
  • I don't know if this has anything to do with your problem, but you shouldn't compare objects with "==". You should use isEqual: instead. – rdelmar Apr 18 '14 at 15:19
  • 1
    Try putting `[_collectionView reloadData]` and `[_collectionView2 reloadData]` in the different `if` branches of `displayTypeSegmentSelected`. I suspect you're setting the datasource too early and not calling `reloadData`. Alternatively, move `[_collectionView2 setDataSource:self];` to the end of the `viewDidLoad` method – Matías R Apr 18 '14 at 15:26
  • Moving setDataSource to end of viewDidLoad has no effect but adding reloadData calls to my if statement in the displayTypeSegmentSelected makes the app crash which is better than before when nothing was happening. I get this message *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 4 beyond bounds [0 .. 3]' – LondonGuy Apr 18 '14 at 15:47
  • Ok I see the cells now. I was telling my numberOfItemsInSection method there were 20 rows. I just set it to use the same dataSource as my first collectionView and I see cells now. What I need to do now is make collection view 2 use the same custom cell. – LondonGuy Apr 18 '14 at 15:50
  • I'm still curious. I recreated a setup like yours and it works with no problem. One thing I noticed is that your `cellForItemAtIndexPath` includes an extra parameter of type `PFObject`. Is that method called from another method named `cellForItemAtIndexPath`? – Matías R Apr 18 '14 at 16:12
  • It's a parse.com version of the cellForItemAtIndexPath method. The object returns current object at index. – LondonGuy Apr 18 '14 at 17:24

2 Answers2

0

Not sure this will fix your issue, but when I have 2 collection views in one controller, I use their tag's to determine which one I am dealing with in a given function, like cellForItemAtIndexPath.

I also have always used different cell identifiers for the two cells and usually different subclasses of uicollectionviewcell.

Where do you create the first collection view and set its delegate?

Augie
  • 1,341
  • 1
  • 11
  • 18
  • I create the first collectionView and it's delegate and dataSource in interface builder. It also has it's own custom cell. I renamed collectionView2's cell identifier and the cells still don't show. – LondonGuy Apr 18 '14 at 15:35
0

Reloading the table data in the method my UISegmentedControl triggers got the cells to show up.

LondonGuy
  • 10,778
  • 11
  • 79
  • 151