简体   繁体   中英

How to add a CollectionView to a ViewController

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.

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

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM