1

I want to add a CollectionView inside my ViewController using the same code that I have on a CollectionViewController.

CollectionViewController.m

@interface StoreViewController ()

@property (readwrite, nonatomic, strong) NSArray *latestProducts;

@end

@implementation StoreViewController

- (void)setLatestProducts:(NSArray *)latestProducts {
    _latestProducts = latestProducts;

    [self.collectionView reloadData];
}

- (Product *)releaseForIndexPath:(NSIndexPath *)indexPath {
    return [self.latestProducts objectAtIndex:indexPath.row];
}

- (void)loadData:(id)sender {
    [self showLoadingView];

    [Product latestProductsWithBlock:^(NSArray *products, NSError *error) {
        self.latestProducts = products;
        dispatch_async(dispatch_get_main_queue(), ^{
            [self hideLoadingView];
        });

        if (error) {
            [[[UIAlertView alloc] initWithTitle:[error localizedDescription] message:[error localizedFailureReason] delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", nil) otherButtonTitles:nil, nil] show];
        }
    }];
}

#pragma mark - UIViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.navigationItem.title = NSLocalizedString(@"Deadstock", nil);

    [self.collectionView registerClass:[ProductCell class] forCellWithReuseIdentifier:@"ProductCell"];

    [self loadData:nil];
}

#pragma mark - UICollectionViewDelegate

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return [self.latestProducts count];
}

#pragma mark - Collection View Cell

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *identifier = @"productCell";

    ProductCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
    cell.product = [self releaseForIndexPath:indexPath];

    return cell;
}

@end

ProductCell.m

@implementation ProductCell

- (void)setProduct:(Product *)product {
    _product = product;

    dispatch_async(dispatch_get_main_queue(), ^{
        [self.image setImageWithURL:self.product.thumbnailImageURL];
    });
    self.image.clipsToBounds = YES;
}

@end

I have an NSObject that parses my cell's content, from my database.

Product.h

@interface Product : NSObject

@property (readonly) NSURL *thumbnailImageURL;

- (instancetype)initWithAttributes:(NSDictionary *)attributes;

+ (void)latestProductsWithBlock:(void (^)(NSArray *products, NSError *error))block;

@end

Following a tutorial I fount online, I created a NSObject file ("ProductDataSource") and on my Storyboard I added an Object to my ViewController and linked it to my CollectionView. I copied the code from my CollectionViewController to ProductDataSource but it's not creating my cells. If I set the numberOfItemsInSection to a number it created the cells but not when I change the code to return [self.latestProducts count]. It might have something to do with "loadData" section I have on my CollectionViewController, since ProductDataSource doesn't have a viewDidLoad method.

- (void)loadData:(id)sender {
    [self showLoadingView];

    [Product latestProductsWithBlock:^(NSArray *products, NSError *error) {
        self.latestProducts = products;
        dispatch_async(dispatch_get_main_queue(), ^{
            [self hideLoadingView];
        });

        if (error) {
            [[[UIAlertView alloc] initWithTitle:[error localizedDescription] message:[error localizedFailureReason] delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", nil) otherButtonTitles:nil, nil] show];
        }
    }];
}

#pragma mark - UIViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.navigationItem.title = NSLocalizedString(@"Deadstock", nil);

    [self.collectionView registerClass:[ProductCell class] forCellWithReuseIdentifier:@"ProductCell"];

    [self loadData:nil];
}

Any help? Thanks.

chrisbedoya
  • 820
  • 7
  • 22

3 Answers3

0

You have to reload the collection view after you get latestProducts. Try to put [self.collectionView reloadData] after [self hideLoadingView];

Miknash
  • 7,888
  • 3
  • 34
  • 46
0

So if I am understanding correctly, you have an existing UICollectionViewController called CollectionViewController and want to reuse the logic in another UIViewController.

a UICollectionViewController is essentially a UIViewController that has a UICollectionView subview and conforms to the UICollectionViewDataSource and UICollectionViewDelegate protocols.

In order to embed a UICollectionView into your UIViewController, you need to create Delegate and DataSource classes for your CollectionView and assign them in the UIViewController.

There are some good code examples here: UICollectionView with UIViewController As Data Source

GitHub Repo with a small single page app using a CollectionView inside a UIViewController: https://github.com/pnavk/CollectionViewSample

Community
  • 1
  • 1
pnavk
  • 4,552
  • 2
  • 19
  • 43
  • Yeah, I did that I'm just having trouble loading the cells. I think it's because in my CollectionViewController I have [self loadData:nil] inside the viewDidLoad but since the NSObject doesn't have a viewDidLoad, that might be the problem. Because if I remove that from my CollectionViewController the cells dont load. – chrisbedoya Jun 17 '15 at 14:49
  • Ah okay so you need to let the collection view know to use the collection of products called latestProducts. Check out the edit to my answer, I put together a simple Single View Application that has a UIViewController with a CollectionView in it. – pnavk Jun 17 '15 at 19:55
0

Put a breakpoint in your cellForItemAtIndexPath method to ensure that method is being hit. If it doesn't get hit, that means you need to set your collection view's datasource.

BevTheDev
  • 563
  • 2
  • 9