How to access IBOutlets of a UICollectionViewCell from a UIViewController? - ios

I implemented a UICollectionView inside a UIViewController. The header cell is created in a separate.xib file and it is implemented in a separate .h and .m files with the IBOutlets and IBActions. The rest of the cells are implemented in the same UIVIewController (The reason is because I added this Parallax effect).
I would like to modify the info of the IBoutlets (labels and buttons) that are in the header cell (CSCellUser.h) from the viewcontroller (RankingViewController) which containts the collectionview, how can I do this?
Cell: CSCellUser.h
#interface CSCellUser : UICollectionViewCell
#property IBOutlet UILabel *myScoreValueLabel;
#property IBOutlet UILabel *myRankingValueLabel;
-(IBAction) sendButtonTouchHandler:(id) sender;
#end
UIViewController: RankingViewController.h
#interface RankingViewController : CommonViewController <UICollectionViewDelegate, UICollectionViewDataSource> {
}
#property IBOutlet UICollectionView *collectionView1;
#end
UIViewController:RankingViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
//Parallax Effect, UICollectionView
// Locate the layout
CSStickyHeaderFlowLayout *layout = (id)self.collectionView1.collectionViewLayout;
if ([layout isKindOfClass:[CSStickyHeaderFlowLayout class]]) {
layout.parallaxHeaderReferenceSize = CGSizeMake(320, 220);
layout.parallaxHeaderAlwaysOnTop = YES;
}
// Locate the nib and register it to your collection view
UINib *headerNib = [UINib nibWithNibName:#"CSHeaderRanking" bundle:nil];
[self.collectionView1 registerNib:headerNib
forSupplementaryViewOfKind:CSStickyHeaderParallaxHeader
withReuseIdentifier:#"TopViewCell"];
//get the position of the user and the ranking (this should update the IBOutlets in the CSCellUser.h)
[self getUserRanking];
//get the ranking of users (this updates each cell of the ranking in cellForItemAtIndexPath)
[self getRanking];
}
- (NSInteger) numberOfSectionsInCollectionView:
(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger) collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section
{
return [ranking count];
}
- (UICollectionViewCell *) collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier: #"UsersCell" forIndexPath:indexPath];
if ([ranking count] > 0)
{
UserRanking *user = [ranking objectAtIndex:indexPath.row]; //Fill the cell
UILabel *usernameLabel = (UILabel *)[cell viewWithTag:101];
usernameLabel.text = user.username;
UILabel *scoreLabel = (UILabel *)[cell viewWithTag:102];
scoreLabel.text = [NSString stringWithFormat:#"%d", user.score];
UILabel *gamesLabel = (UILabel *)[cell viewWithTag:103];
gamesLabel.text =[NSString stringWithFormat:#"%d", user.tries];
}
return cell;
}
//Header
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
UICollectionReusableView *reusableview = nil;
if ([kind isEqualToString:CSStickyHeaderParallaxHeader]) {
reusableview = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:#"TopViewCell" forIndexPath:indexPath];
}
return reusableview;
}
EDIT:
This is how I am trying to change one of the labels from cellForRowAtIndexPath but it does not change.
CSHeaderRanking *topcell = [collectionView dequeueReusableCellWithReuseIdentifier: #"TopCell" forIndexPath:indexPath];
topcell.myScoreValueLabel.text = #"32";

If TopCell is mapped in its xib, all you have to do is refer to its properties. If you want to customize, you'll need to over-ride the CCSticky... and refer to it in your xib and this class.

Related

Implementing the title under image in UICollectionView

Implementing the title under the image in UICollectionView. I am new in this ios application development. I want to implement the title under the image view in collectionView. Does anybody know the answer?
I have initialized the label programmatically and add it in the collectionview but it did not show the title
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
static NSString *identifier = #"Cell";
//MARK:-To set the variables
self.imageArray=[NSArray arrayWithObjects:#"1.png",#"2.png",#"3.jpeg",#"4.jpeg",#"1.png",#"2.png",#"3.jpeg",#"4.jpeg"];
self.imageText=#[#"1",#"2",#"3",#"4",#"5",#"6",#"7",#"8"];
// for image
UIImageView *recipeImageView = [[UIImageView alloc] init];
recipeImageView.frame = self.collectionView.bounds;
[self.collectionView addSubview:recipeImageView];
recipeImageView.tag = 100;
// for the label
UILabel *title=[[UILabel alloc]init];
title.tag = 200;
[self.collectionView addSubview:title];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:identifier];
}
//MARK:-To set the number of sections in UICOLLECTIONVIEW
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.imageArray.count;
}
//MARK:-To set the content to the UICollectionView
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{
static NSString *identifier = #"Cell";
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
//MARK:-To set the image dynamically to the UICollectionViewCell
UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.image = [UIImage imageNamed:[self.imageArray objectAtIndex:indexPath.row]];
[self.view addSubview:recipeImageView];
cell.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:[self.imageArray objectAtIndex:indexPath.row]]];
//MARK:- To set the label dynamically to the UICollectionViewCell
UILabel *imageTitle=(UILabel *)[cell viewWithTag:200];
[imageTitle setText:self.imageText];
return cell;
}
#end

How to change a UICollection View cell size form IBAction in cell object

I am developing a uiCollection view, In which i have 4 cells, on 4th cell i have uiview which hold button and ui textview. once i tap button the textview should reveal and close.
I don't know how to handle this, how to increase particular cell size on inaction in cell object
UICollectionview.M
#pragma mark - UICollectionView DataSource & Delegate methods
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 4;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section==2) {
UICollectionViewCell * cell =[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier2 forIndexPath:indexPath];
return cell;
}
else if(indexPath.section==1){
UICollectionViewCell * cell =[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier1 forIndexPath:indexPath];
return cell;
}
else if(indexPath.section==0){
UICollectionViewCell * cell =[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
return cell;
}
else{
infoCell * cell =[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier3 forIndexPath:indexPath];
return cell;
}
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.section == 3) {
return CGSizeMake(self.width, self.height);
}
else{
return CGSizeMake(309, 300);
}
}
#end
cell object
cellobject.h
#interface InfoCell : UICollectionViewCell
{
BOOL toggleIsOn;
}
#property (weak, nonatomic) IBOutlet UIView *infoView;
#property (weak, nonatomic) IBOutlet UIButton *dropDownButton;
#property (weak, nonatomic) IBOutlet UITextView *infoDescrip;
#end
cell object.m
-(IBAction)revealDescription:(id)sender{
if (toggleIsOn)
{
self.infoDescrip.hidden= YES;
self.infoView.frame=CGRectMake(0, 0, 309,44);
}
else
{
self.infoDescrip.hidden= NO;
NSDictionary *attributes = #{NSFontAttributeName: [UIFont fontWithName:#"HelveticaNeue" size:14]};
CGRect rect = [self.infoDescrip.text boundingRectWithSize:CGSizeMake(300, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes context:nil];
self.infoDescrip.frame= CGRectMake(0, 46, 300, rect.size.height);
self.infoView.frame=CGRectMake(0, 0, 309, rect.size.height+50);
}
toggleIsOn = !toggleIsOn;
[self.dropDownButton setImage:[UIImage imageNamed:toggleIsOn ? #"arrow_down_blue" :#"arrow_right_blue"] forState:UIControlStateNormal];
}
I am struggling to get out of this any help?
You can save indexPath of your particular cell in #property. Create 2 cases in HeightForRowAtIndexPath: with BOOL flag: one for normal size and one for big.
Then you get button tap, you activate some BOOL flag and reload cell with animation.

Use more than one UICollectionViews in a ViewController

I tried to use two UICollectionViews in a single ViewController. Application crashed with the following error
reason: 'could not dequeue a view of kind: UICollectionElementKindCell with identifier ItemCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard
This is my implementation how looks like
HomeViewController.h
UICollectionView *colloctionViewItems;
UICollectionView *colloctionViewCats;
#property (nonatomic, retain) IBOutlet UICollectionView *colloctionViewItems;
#property (nonatomic, retain) IBOutlet UICollectionView *colloctionViewCats;
HomeViewController.m
#synthesize colloctionViewCats, colloctionViewItems;
- (void)viewDidLoad{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
// read ItemList plist
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSDictionary *dicCats = [appDelegate readPlistIntoDictWithFile:#"CatagoryList.plist"];
// arrCategories
arrCats = [[NSArray alloc]initWithArray:[dicCats objectForKey:#"Catagories"]];
[self.colloctionViewItems registerClass:[ItemCell class] forCellWithReuseIdentifier:#"ItemCell"];
[self.colloctionViewCats registerClass:[CatCell class] forCellWithReuseIdentifier:#"CatCell"];
[colloctionViewItems reloadData];
[colloctionViewCats reloadData];
}
#pragma mark for Collection View Delegate methods
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section
{
if(view == colloctionViewItems){
return [arrCats count];
}
if(view == colloctionViewCats){
return [arrCats count];
}
return 0;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
return CGSizeZero;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
ItemCell *iCell = [cv dequeueReusableCellWithReuseIdentifier:#"ItemCell" forIndexPath:indexPath];
CatCell *cCell = [cv dequeueReusableCellWithReuseIdentifier:#"CatCell" forIndexPath:indexPath];
if(cv == colloctionViewItems){
iCell.lblBtnTitle.text = [arrCats objectAtIndex:indexPath.row];
return iCell;
}
if(cv == colloctionViewCats){
cCell.lblBtnTitle.text = [arrCats objectAtIndex:indexPath.row];
return cCell;
}
return iCell;
}
If I removed one UICollectionView, all works fine. Any ideas please.
FYI: I have created Custom Collection Cell class as "ItemCell" and "CatCell" correctly (without using nibs)
It's because you dequeue both cell at the same time, even if the collection view hasn't contain the right cell. You should first check which collection view is asking about cell and after that dequeue the right one:
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
if(cv == colloctionViewItems){
// Item collection view contain item cell so you can safety dequeue it.
// if you try to dequeue CatCell it will fail this is why you had this issue before
ItemCell *iCell = [cv dequeueReusableCellWithReuseIdentifier:#"ItemCell" forIndexPath:indexPath];
iCell.lblBtnTitle.text = [arrCats objectAtIndex:indexPath.row];
return iCell;
}
if(cv == colloctionViewCats){
CatCell *cCell = [cv dequeueReusableCellWithReuseIdentifier:#"CatCell" forIndexPath:indexPath];
cCell.lblBtnTitle.text = [arrCats objectAtIndex:indexPath.row];
return cCell;
}
return nil;
}

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