I am having a hard time figuring out why cell.imageview property doesn't show me image below. UIImage is not nil, cells are created, if I assign a background to cell, it is displayed which proves I am creating collectionview and my cells correctly. I programmatically create my collectionview and don't use any IB or interface builder. I have done this lots of times before, but I am really scratching my head with this one.
Thanks in advance.
#interface MainViewController : UIViewController
#property(strong, nonatomic) UICollectionView *collectionView;
#end
#interface MainViewController ()<
UICollectionViewDataSource, UICollectionViewDelegate,
UICollectionViewDelegateFlowLayout, UIGestureRecognizerDelegate>
#property(nonatomic, strong) MHTransitionShowDetail *interactivePushTransition;
#property(nonatomic) CGPoint lastPoint;
#property(nonatomic) CGFloat startScale;
#property(strong, nonatomic) NSMutableArray *carImages;
#end
#implementation MainViewController
- (instancetype)init {
self = [super init];
if (self) {
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_carImages = [#[
#"chevy_small",
#"mini_small",
#"rover_small",
#"smart_small",
#"highlander_small",
#"venza_small",
#"volvo_small",
#"vw_small",
#"ford_small",
#"nissan_small"
] mutableCopy];
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UICollectionViewFlowLayout *layout =
[[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(106, 106);
layout.minimumLineSpacing = 1.0;
layout.minimumInteritemSpacing = 1.0;
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame
collectionViewLayout:layout];
[self.collectionView setDataSource:self];
[self.collectionView setDelegate:self];
self.collectionView.alwaysBounceVertical = YES;
[self.collectionView setContentInset:UIEdgeInsetsMake(20, 10, 10, 10)];
[self.collectionView registerClass:[IKGCollectionViewCell class]
forCellWithReuseIdentifier:#"myCell"];
self.collectionView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:self.collectionView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma CollectionView & FlowLayout methods
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(120, 120);
}
- (NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section {
return self.carImages.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
IKGCollectionViewCell *cell =
[collectionView dequeueReusableCellWithReuseIdentifier:#"myCell"
forIndexPath:indexPath];
long row = [indexPath row];
UIImage *image = [UIImage imageNamed:self.carImages[row]];
cell.imageView.userInteractionEnabled = YES;
cell.imageView.image = image;
NSLog(#"cell.image view %#", image);
// [self makeCell:(IKGCollectionViewCell *)cell atIndexPath:indexPath];
return cell;
}
}
#end
#interface IKGCollectionViewCell : UICollectionViewCell
#property(nonatomic, strong) UIImageView *imageView;
#end
#implementation IKGCollectionViewCell
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.imageView = [[UIImageView alloc] initWithFrame:self.bounds];
NSLog(#"self.bounds is %#", NSStringFromCGRect(self.bounds));
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
self.imageView.frame = self.contentView.bounds;
}
#end
You missed to add the cell's imageView as a it's subview.
So in cell's initWithFrame
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.imageView = [[UIImageView alloc] initWithFrame:self.bounds];
//Add imageView as subview
[self addSubview:self.imageView];
NSLog(#"self.bounds is %#", NSStringFromCGRect(self.bounds));
}
return self;
}
Related
I decided to opt out of using a Xib to generate my custom UICollectionViewCell (StoneCell), so I've been struggling with how to go about properly initializing it programmatically.
I implemented:
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGSize size = [MainScreen screen];
CGFloat width = size.width;
CGFloat item = (width*60)/320;
return CGSizeMake(item, item);
}
as well as:
[self.collectionView registerClass:[StoneCell class] forCellWithReuseIdentifier:#"stoneCell"];
in my UICollectionView controller.
In my StoneCell.m, I tried the following:
-(id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
StoneCell* stone = [[StoneCell alloc] initWithFrame:frame];
self = stone;
}
return self;
}
but to no avail. When I build and run, I crash on self = [super initWithFrame:frame]; When I check the value of frame, it's correctly set at {{0,0},{70,70}} which is what it should be on the 6s. However, the object stone (as well as self) are both reported as nil.
Clearly this is not correct, so I wanted to know how to initialize the cell properly.
I am also properly dequeuing the cell in:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
so that's taken care of.
Your initializer should be
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
return self;
}
With your original implementation
-(id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
StoneCell* stone = [[StoneCell alloc] initWithFrame:frame];
self = stone;
}
return self;
}
you have an infinite recursion of initWithFrame.
// In AMAImageViewCell.h
#import <UIKit/UIKit.h>
#interface AMAImageViewCell : UICollectionViewCell
#property (strong, readonly, nonatomic) UIImageView *imageView;
#end
// In AMAImageViewCell.m
#implementation AMAImageViewCell
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_imageView = [[UIImageView alloc] initWithFrame:self.contentView.bounds];
_imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
_imageView.clipsToBounds = YES;
_imageView.contentMode = UIViewContentModeScaleAspectFill;
_imageView.layer.cornerRadius = 0.0;
[self.contentView addSubview:_imageView];
}
return self;
}
#end
/******In the class where you have to use **********/
[self.collectionView registerClass:[AMAImageViewCell class] forCellWithReuseIdentifier:ImageCellIdentifier];
// In cellForItemAtIndexPath
AMAImageViewCell *cell = [collectionViewLocal dequeueReusableCellWithReuseIdentifier:ImageCellIdentifier
forIndexPath:indexPath];
If I use this code to indent from left, everything is indented (separator + content)
table.contentInset = UIEdgeInsetsMake(0, 20, 0, 0);
Same if I use this:
cell.layoutMargins = UIEdgeInsetsMake(0, 20, 0, 0);
This doesn't help neither, because it doesn't move the image.
cell.indentationLevel = 10;
You can use a CustomTableCell to get what you want:
At first, in ViewController:
#import "ViewController.h"
#import "MyTableCell.h"
#interface ViewController ()
#property UITableView *tableView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
_tableView.separatorStyle = UITableViewCellSelectionStyleNone;
_tableView.backgroundColor = [UIColor grayColor];
_tableView.dataSource = self;
_tableView.delegate = self;
[self.view addSubview:_tableView];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 20;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MyTableCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyCell"];
if (nil == cell) {
cell = [[MyTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyCell"];
}
//Update data for cell
return cell;
}
#end
This is MyTableCell.h:
#import "MyTableCell.h"
#interface MyTableCell()
#property UIView *containerView;
#property UIView *separationLine;
#end
#implementation MyTableCell
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
_containerView = [[UIView alloc] init];
_containerView.backgroundColor = [UIColor redColor];
[self addSubview:_containerView];
_separationLine = [[UIView alloc] init];
_separationLine.backgroundColor = [UIColor blackColor];
[self addSubview:_separationLine];
return self;
}
-(void)layoutSubviews{
_containerView.frame = CGRectMake(20, 0, self.frame.size.width-20, self.frame.size.height-1);
_separationLine.frame = CGRectMake(10, self.frame.size.height-1, self.frame.size.width-10, 1);
}
#end
And this is the screenshot for the code:
You can modify the code in "layoutSubviews" as your wish.
Hope it can help you.
I have a view controller (that sits in a tab bar controller), but need to add a collection view to that controller. I see lots of tutorials on google but they all seem to point to creating a UICollectionViewController and starting in viewDidLoad. But how do I do it in a subview?
I have my view controller.m file like so:
- (void) createView // called from viewDidLoad
{
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 64.0, screenWidth, screenHeight)];
[scrollView.layer addGradient];
ACollectionView *theview = [[ACollectionView alloc] init];
[self.view addSubview:theview];
}
Next I started a UICollectionView subclass called ACollectionView.h
#interface ACollectionView : UICollectionView
#end
And the .m file is this:
#import "ACollectionView.h"
#implementation BestCollectionView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
Where do I start the collection view, in the initWithFrame?
I am trying to follow this:
Creating a UICollectionView programmatically
Is my paradigm correct?
#property (nonatomic, strong) UICollectionView *collectionView;
- (void)viewDidLoad
{
[super viewDidLoad];
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
self.collectionView = [[UICollectionView alloc] initWithFrame:self.yourSubview.frame collectionViewLayout:layout];
[self.collectionView setDataSource:self];
[self.collectionView setDelegate:self];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"cellIdentifier"];
[self.yourSubview addSubview:self.collectionView];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 50;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
cell.backgroundColor = [UIColor redColor];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(100, 100);
}
I am totally new for collection view, please help me with scrolling cell vertically and horizontally in collection view :
viewcontroller.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UICollectionViewDataSource,UICollectionViewDelegate>
{
UICollectionView *collectionView;
}
#end
viewcontroller.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
collectionView=[[UICollectionView alloc] initWithFrame:self.view.frame
collectionViewLayout:layout];
[collectionView setDataSource:self];
[collectionView setDelegate:self];
[collectionView registerClass:[UICollectionViewCell class]
forCellWithReuseIdentifier:#"cellIdentifier"];
[collectionView setBackgroundColor:[UIColor redColor]];
[self.view addSubview:collectionView];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 9;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
cell.backgroundColor=[UIColor greenColor];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(100, 100);
}
#end
I'm a little late here, but just in case anybody else looks this up, you can easily set your collection view scroll direction by using UICollectionViewFlowLayout.
Create an instance of UICollectionViewFlowLayout
Set the scrollDirection to UICollectionViewScrollDirectionHorizontal
Rejoice.
-(instancetype) init
{
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
layout.itemSize = CGSizeMake(106, 106);
layout.minimumInteritemSpacing = 1;
layout.minimumLineSpacing = 1;
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self= [super initWithCollectionViewLayout:layout];
return self;
}
you can scroll the collectionview programmaticaly with the follwing methods of UICollectionView class:
[collectionView scrollsToTop];
[collectionView scrollToItemAtIndexPath:<#(NSIndexPath *)#> atScrollPosition:<#(UICollectionViewScrollPosition)#> animated:<#(BOOL)#>];
[collectionView scrollRectToVisible:<#(CGRect)#> animated:<#(BOOL)#>];
I have a uiviewcontroller with a subview which is a uicollection view. My view controller implements all of the collectionview delegates. For some reason some of the cells are black (when i scroll they appear , it seems randomly) My code is:
#import "NewGalleryViewController.h"
#interface MyCell : UICollectionViewCell
#property (nonatomic,strong) UIImageView *imageView;
#end
#implementation MyCell
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
NSLog(#"frame = %#\n", NSStringFromCGRect(frame));
if (self)
{
self.imageView = [[UIImageView alloc] initWithFrame:frame];
[self.contentView addSubview:self.imageView];
}
return self;
}
#end
#interface NewGalleryViewController () <UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>
#property (nonatomic,strong) UICollectionView *collectionView;
#end
#implementation NewGalleryViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
[layout setItemSize:CGSizeMake(75, 75)];
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
[self.collectionView registerClass:[MyCell class] forCellWithReuseIdentifier:#"newcell"];
[self.view addSubview:self.collectionView];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 100;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
MyCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"newcell" forIndexPath:indexPath];
cell.imageView.image = [UIImage imageNamed:#"114"];
return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%ld",(long)indexPath.row);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(75,75);
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
return UIEdgeInsetsMake(0, 0, 0, 0);
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return 10;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
return 0;
}
#end
I fixed your problem
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
self.imageView = [[UIImageView alloc] initWithFrame:self.bounds]; // earlier it was frame
[self.contentView addSubview:self.imageView];
}
return self;
}
While creating the content image view do not use frame of the cell instead of use self.bounds. Iam not sure about the reason. Frame can be different at that time bounds will give the actual values
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
NSArray *arrayOfviews = [[NSBundle mainBundle]loadNibNamed:#"PersonCollectionViewCell" owner:self options:nil];
self = [[arrayOfviews objectAtIndex:0]isKindOfClass:[UICollectionViewCell class]] ? [arrayOfviews objectAtIndex:0] : nil;
}
return self;
}