Keep reference of views from collectionView is doubled - ios

Trying to keep reference in arrays of all views that being added to collection view .
So what happens, is that i have this array with the data, but when i scroll down the collection, it calls the reusable cells function ,and try to add them again to my array ,although i am checking if they are there before adding them again :
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
//quantity
UILabel *quantityL=[[UILabel alloc] initWithFrame:CGRectMake(cell.frame.size.width/10,cell.frame.size.width/10, cell.frame.size.width/5,cell.frame.size.width/5)];
quantityL.text=[NSString stringWithFormat:#"%d",quantity];
quantityL.font=[UIFont fontWithName:[Globals sharedGlobals].titleFont size:[Globals sharedGlobals].badgeSize];
quantityL.textAlignment=NSTextAlignmentCenter;
//more and more stuff
[cell addSubview:quantityL]; //add to cell
if(![allQuantities containsObject:quantityL]) //check if already in array!
[allQuantities addObject:quantityL]; //add to array
i can see that allQuantities array is changing its size... why ?

To properly reuse and set frames: code for your controller:
#define kMyCellIdentifier #"kMyCellIdentifier"
- (void)viewDidLoad {
[super viewDidLoad];
//...
[self.collectionView setDelegate:self];
[self.collectionView setDataSource:self];
[self.collectionView registerClass:[MyCollectionViewCell class] forCellWithReuseIdentifier:kMyCellIdentifier];
}
#pragma mark - UICollectionViewDelegate && UICollectionViewDataSource
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MyCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kMyCellIdentifier forIndexPath:indexPath];
[cell.textLabel setText:#"blah"];
return cell;
}
And your cell subclass:
#interface MyCollectionViewCell : UICollectionViewCell
#property(nonatomic, readonly) UILabel *textLabel;
#end
#implementation MyCollectionViewCell
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
_textLabel = [[UILabel alloc] init];
[self.textLabel setTextAlignment:NSTextAlignmentCenter];
[self.contentView addSubview:self.textLabel];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
CGRect rect = self.contentView.bounds;
[self.textLabel setFrame:rect];
}

Related

Custom uicollectionview - pass data

I have a UICollectionView that use a custom cell:
[_collectionView registerNib:[UINib nibWithNibName:#"CollectionViewCell" bundle:nil] forCellWithReuseIdentifier:#"cellIdentifier"];
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
cell.articolo = [_array objectAtIndex:indexPath.row];
I want to pass the object articolo to my cell, so I create a property:
#property (strong, nonatomic) NSMutableDictionary *articolo;
but if I try to read the property in one of this method:
#implementation CollectionViewCell
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {NSLog(#"Articolo: %#",_articolo);}
return self;
}
- (id)initWithCoder:(NSCoder*)aDecoder
{
self = [super initWithCoder:aDecoder];
if(self) {NSLog(#"Articolo: %#",_articolo);}
return self;
}
- (void) awakeFromNib
{
[super awakeFromNib];
NSLog(#"Articolo: %#",_articolo);
}
I get always a null value, where is the error? how can I pass this object to my cell?
Your code is perfect, you will always get null value in any of the above method because it is called when your cell is initialized.
You can get value by putting setter method like this.
-(void)setArticolo:(NSMutableDictionary *)articolo {
_articolo = articolo;
}
Try this, it may help u.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
cell.articolo =[[NSMutableDictionary alloc] initWithDictionary:[_array objectAtIndex:indexPath.row]];
return cell;
}

Small UIImage view in custom UICollectionViewCell

I have UICollectionViewCell
#import "DBPhotoCollectionViewCell.h"
#define IMAGEVIEW_BORDER_LENGTH 5
#implementation DBPhotoCollectionViewCell
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self setup];
}
return self;
}
/* Need to implement the initWithCoder method since this class will be created from the storyboard */
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self){
[self setup];
}
return self;
}
/* Create the UIImageView and add it to the cell's contentView in code. */
-(void)setup
{
self.imageView = [[UIImageView alloc] initWithFrame:CGRectInset(self.bounds, IMAGEVIEW_BORDER_LENGTH, IMAGEVIEW_BORDER_LENGTH)];
[self.contentView addSubview:self.imageView];
}
#end
And call this Cell from CollectionViewController class
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Photo Cell";
DBPhotoCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
cell.imageView.image = [UIImage imageNamed:#"Astronaut.jpg"];
// Configure the cell
return cell;
}
But I have one problem when I start my application my picture is showed with small size. What I missed?
http://screencast.com/t/ia8tE05P6yc
http://screencast.com/t/33N4AhT7
cell.imageView, imageView object is not same as which you have added on cell of Interface Builder. UICollectionViewCell has default size UIImageView which are accessing, you can access your customView imageView in cellForIndexPath method of collectionView by linking imageView of subClass DBPhotoCollectionViewCell in interface builder you don't need to add [self.contentView addSubview:self.imageView]; in setup method.
Second approach would be assign tag value to imageView when you adding to cell contentView
/* Create the UIImageView and add it to the cell's contentView in code. */
-(void)setup
{
self.imageView = [[UIImageView alloc] initWithFrame:CGRectInset(self.bounds, IMAGEVIEW_BORDER_LENGTH, IMAGEVIEW_BORDER_LENGTH)];
self.imageView.tag=1;
[self.contentView addSubview:self.imageView];
}
//And access imagView in cellForIndexPath
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Photo Cell";
DBPhotoCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
UIImageView *imageView=[cell.contentView viewWithTag:1];
imageView.image = [UIImage imageNamed:#"Astronaut.jpg"];
// Configure the cell
return cell;
}

UIViewController does not load its UICollectionView property

I have a UITabBarController that contains 2 UIViewControllers. The 2nd UIViewController crashes when ever I try to show from the 1st UIViewController.
The 2nd UIViewController crashes because of its UICollectionView declared as a private property.
I get a EXC_BAD_ACCESS so I think that the 2nd UIViewController tries to do [self setCollectionView] but when its property self.collectionView is not init yet (still nil).
I don't understand why it behaves so - I have no problem implementing the UICollectionView the same way in the 1st UIViewController. Here is the .m file of the 2nd UIViewController :
#interface WorkoutViewController () <UICollectionViewDataSource, UICollectionViewDelegate, DAPageControlViewDelegate>
#property (strong, nonatomic) UICollectionView *collectionView;
#property (strong, nonatomic) DAPageControlView *pageControlView;
#end
#implementation WorkoutViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self createCollectionView];
[self createPageView];
// Constraints
// CollectionView
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view);
}];
// PageControl
[self.pageControlView mas_makeConstraints:^(MASConstraintMaker *make) {
make.trailing.equalTo(self.view);
make.leading.equalTo(self.view);
make.height.equalTo(screenAdjustedSizeFrom(15));
make.bottom.equalTo(self.view).offset(screenAdjustedSizeFrom(-15).floatValue);
}];
// Wake up collectionView
[self.collectionView reloadData];
}
-(void)createCollectionView {
// Layout
UICollectionViewFlowLayout *collectionViewLayout = [[UICollectionViewFlowLayout alloc] init];
collectionViewLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
// UICollectionView
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:collectionViewLayout];
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
[self.view addSubview:self.collectionView];
// Behavior
self.collectionView.pagingEnabled = YES;
// Appearance
self.collectionView.backgroundColor = [Color colorWithName:nil alpha:0.2f];
self.collectionView.showsHorizontalScrollIndicator = NO;
// Register cells
//[self.collectionView registerClass:[TrackingSetCollectionViewCell class] forCellWithReuseIdentifier:TrackingSetCollectionViewCellIdentifier]; }
-(void)createPageView {
// Support for pagination - DAPageControlView
self.pageControlView = [[DAPageControlView alloc] initWithFrame:CGRectZero];
self.pageControlView.delegate = self;
[self.view addSubview:self.pageControlView];
self.pageControlView.hidden = YES; // do not show the dots
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return fetchManagedObjectsFromEntity(#"Autor", #[[NSSortDescriptor sortDescriptorWithKey:#"autorID" ascending:YES]], nil, self.managedObjectContext).count + 1; // +1 for testing !
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
//test
UICollectionViewCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
if (indexPath.row==0) {
cell.backgroundColor = [UIColor blueColor];
}
if (indexPath.row==1) {
cell.backgroundColor = [UIColor redColor];
}
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return self.collectionView.bounds.size;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 0.0;
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(0, 0, 0, 0);
}
#pragma mark - DAPageControlView Delegate
- (void)pageControlViewDidChangeCurrentPage:(DAPageControlView *)pageControlView
{
[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:pageControlView.currentPage inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
}
Problem solved - I forgot to register a class for the UICollectionViewCell. I thought it was not necessary for to do so for the 'default' class UICollectionViewCell but since the UICollectionView is added programmatically, it makes sense.

How to add photos into UICollectionViewCell?

I have creates a UICollectionView which I currently have showing white cells. I have been following this tutorial to figure out how to use the delegate methods etc.
I have made it up to the point where you create the Creating custom UICollectionViewCells however in this example the tutorial he tells you to open your story board etc. I don't have a story board. I have tried to follow the instructions to create the view but with my own .xib file and I just cannot get anything to work.
How can I check out where my delegate methods are at this point?
// this is how I load the collection view
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
photoCollectionView =[[UICollectionView alloc] initWithFrame:CGRectMake(10.0, 40.0, 480.0, 713.0) collectionViewLayout:layout];
photoCollectionView.dataSource = self;
photoCollectionView.delegate = self;
[self.view addSubview:photoCollectionView];
[photoCollectionView.layer setBorderColor: [[UIColor lightGrayColor] CGColor]];
[photoCollectionView.layer setBorderWidth: 1.0];
[self.photoCollectionView reloadData];
// this is what my delegate methods look like
#pragma mark - CollectionView Delegates
#pragma mark -- UICollectionView Datasource
// 1
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section {
return [imageArray count];
}
// 2
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
return 1;
}
// 3
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"PhotoCell" forIndexPath:indexPath];
// I think this is where I want to set my image for the cell
NSDictionary *currentPhotoDict = [imageArray objectAtIndex:indexPath.row];
UIImage *imageForCollection = [UIImage imageWithData:[currentPhotoDict objectForKey:#"DImage"]];
// but I have no idea where to pass the imag....
cell.backgroundColor = [UIColor whiteColor];
return cell;
}
#pragma mark -- UICollectionView Delegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
// TODO: Select Item
}
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
// TODO: Deselect item
}
#pragma mark –- UICollectionViewDelegate FlowLayout
// 1
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGSize retval = CGSizeMake(210, 157+20); // add 20 for labels under neath.. might need to adjust this.
return retval;
}
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(50, 20, 50, 20);
}Subview:photoCollectionView];
[photoCollectionView.layer setBorderColor: [[UIColor lightGrayColor] CGColor]];
[photoCollectionView.layer setBorderWidth: 1.0];
[self.photoCollectionView reloadData];
As you can see in collectionView:cellForItemAtIndexPath I have my image ready
NSDictionary *currentPhotoDict = [imageArray objectAtIndex:indexPath.row];
UIImage *imageForCollection = [UIImage imageWithData:[currentPhotoDict objectForKey:#"DImage"]];
I just need to know how to load it into the collectionviewcell.
Please try to use like this....
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"PhotoCell" forIndexPath:indexPath];
// I think this is where I want to set my image for the cell
NSDictionary *currentPhotoDict = [imageArray objectAtIndex:indexPath.row];
UIImage *imageForCollection = [UIImage imageWithData:[currentPhotoDict objectForKey:#"DImage"]];
[cell setBackgroundColor:[UIColor colorWithPatternImage:imageForCollection];// Add your image here........
// but I have no idea where to pass the imag....
cell.backgroundColor = [UIColor whiteColor];
return cell;
}
i hope it will help you...
I have UICollectionViewCell with name PhotoCell. and have label and imageview as properties.
This is how u can set Image to cell. May this is your requirement or not. I dont know. Try this
You need to set identifier at Xib of your UICollectionViewCell as MY_CELL or some other name.Then
.m
static NSString *cellidentity=#"MY_CELL";
At ViewDidLoad method
UINib *nib;
nib = [UINib nibWithNibName:#"PhotoCell" bundle:nil];
[self.collectionView registerNib:nib forCellWithReuseIdentifier:cellidentity];
My UICollectionViewCell .h is
#interface PhotoCell : UICollectionViewCell
#property (retain, nonatomic) IBOutlet UILabel* label;
#property (retain, nonatomic) IBOutlet UILabel* timelineLabel;
#property (retain, nonatomic) IBOutlet UIImageView* yourImageView;
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{
// PhotoCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"PhotoCell" //forIndexPath:indexPath];
PhotoCell *cell = [cv dequeueReusableCellWithReuseIdentifier:cellidentity forIndexPath:indexPath];
NSDictionary *currentPhotoDict = [imageArray objectAtIndex:indexPath.row];
UIImage *imageForCollection = [UIImage imageWithData:[currentPhotoDict objectForKey:#"DImage"]];
// but I have no idea where to pass the imag....
cell.label.text = [NSString stringWithFormat:#"%d",indexPath.item];
cell.yourImageView.image=imageForCollection;
return cell;
}
Hope it helps You....

Change attributes of a UICollectionViewCell in didSelectItemAtIndexPath

I am configuring a UICollectionViewCell in a subclass, it adds 2 subviews to the contentView property, both are UIImageView and both have the hidden property set to YES. These subviews are "checked" and "unchecked" images that overlay the primary UIImageView in the cell to indicate whether or not the current cell is selected using UICollectionView's "multiple select" feature.
When the cell is tapped, collectionView:didSelectItemAtIndexPath: is called on the delegate, and I'd like to setHidden:NO on the "checked" UIImageView. Calling this on the cell does nothing at all -- the cell is seemingly locked in its originally drawn state.
Is it possible to make changes to a cell outside collectionView:cellForItemAtIndexPath:? I have tried manually adding subviews within collectionView:didSelectItemAtIndexPath:, but it just makes absolutely no change to the UI. I have verified that the delegate method is getting called, it's just not making my cell changes.
- (void) collectionView(UICollectionView *)cv didSelectItemAtIndexPath(NSIndexPath *)indexPath {
ShotCell *cell = [self collectionView:cv cellForItemAtIndexPath:indexPath];
UILabel *testLabel = UILabel.alloc.init;
testLabel.text = #"FooBar";
testLabel.sizeToFit;
[cell.contentView.addSubview testLabel];
}
The way you're trying to do this is incorrect. You need to keep a reference to the selected cell or cells in a property. In this example, I use an array to hold index paths of the selected cells, then check whether the index path passed in to cellForItemAtIndexPath is contained in that array. I unselect the cell if you click on one that's already selected:
#interface ViewController ()
#property (strong,nonatomic) NSArray *theData;
#property (strong,nonatomic) NSMutableArray *paths;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.paths = [NSMutableArray new];
self.theData = #[#"One",#"Two",#"Three",#"Four",#"Five",#"Six",#"Seven",#"Eight"];
[self.collectionView registerNib:[UINib nibWithNibName:#"CVCell" bundle:nil] forCellWithReuseIdentifier:#"cvCell"];
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
[self.collectionView setCollectionViewLayout:flowLayout];
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.theData.count;
}
-(CVCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"cvCell";
CVCell *cell = (CVCell *) [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
cell.label.text = self.theData[indexPath.row];
if ([self.paths containsObject:indexPath]) {
[cell.iv setHidden:NO]; // iv is an IBOutlet to an image view in the custom cell
}else{
[cell.iv setHidden:YES];
}
return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
if ([self.paths containsObject:indexPath]) {
[self.paths removeObject:indexPath];
}else{
[self.paths addObject:indexPath];
}
[self.collectionView reloadItemsAtIndexPaths:#[indexPath]];
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(150, 150);
}

Resources