ios7 UILabel in UICollectionViewCell does not show - ios

Deployment target 7.0,
Running on iOS7.1,
Xcode 5
I have a UIImageView "comicImage" and UILabel "comicTitle" set up using IB on the UICollectionViewCell.
comicTitle uses these settings:
The IBOutlet is properly hooked up. The view cell is properly registered to the collectionView. I have output the title in
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
on the console and the text of the title did get assigned to comicTitle.
When I run the app, comicImage shows up, but comicTitle does not show up. I have ensured that the alpha of comicTitle is set to 1.0.
This same piece of code worked in a previous app with deployment target set to iOS6.
I have no idea what went wrong. Can anyone shed light on this?
Thanks in advance!
Edit:
-(void)viewDidLoad {
UINib *comicStripCellNib = [UINib nibWithNibName:#"ComicStripViewCell" bundle:ni];
[_comicStripCollectionView registerNib:comicStripCellNib forCellWithReuseIdentifier:#"comicStripCell"];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
ComicStripViewCell *comicStripViewCell = [collectionView dequeueReusableCellWithReuseIdentifier:#"comicStripCell" forIndexPath:indexPath];
comicStripViewCell.comicTitle.text = #"This is a title";
comicStripViewCell.comicImage.image = [UIImage imageNamed:#"thisImage.png"];
NSLog(#"comicStripViewCell.comicTitle.text = %#", comicStripViewCell.comicTitle.text);
return (UICollectionViewCell *)comicStripViewCell;
}
I do not think it is a problem with the code.

Some suggestions.
Apply a background color to check where your label lies
Mess with the label frame values. Give a trial and error and see whether your label has been misplaced somewhere.
If you have used constraints make sure you have given the specific constraints correctly.
Check whether your comicImage is not overlapping your label
You can actually see a preview of your xib in xcode(i.e, After you designed your cell you can confirm how your cell will actually display in the screen). Refer the below screenshot

you can do it by given the tag value below code is the sample code for UILabel tag approach
In storyBoard Drag the UILabel from the Object library in to the collection view cell
Give the Tag value 30 to UILabel from the Attributes Inspector
Get the UILabel object from the below code
write the below code in the Collection view DataSource method
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
ComicStripViewCell *comicStripViewCell = [collectionView dequeueReusableCellWithReuseIdentifier:#"comicStripCell" forIndexPath:indexPath];
UILabel *comicTitle = (UILabel *)[comicStripViewCell viewWithTag:30];// get the UILabel object by its tag value
comicTitle.text = #"testing"; // assign the value that you want for comicTitle
return (UICollectionViewCell *)comicStripViewCell;
}
otherwise share the piece of code that you have.
may be your label frame has been misplaced somewhere.
Please check UILabel Frame also

Related

iOS first UICollectionViewCell image not loading ONLY after using constraints

Without constraints my UICollectionViewCells load immediately without any problems at all. When I put constraints on in storyboard so the image view is horizontal and vertically centered to the cell, the first image cell does not load. I have to scroll a few times and then back to the beginning for the first image cell to show. Take the constraints off and it goes back to working perfectly fine.
I thought maybe the images weren't getting loaded in time but that doesn't appear to be the case.
What am I missing?
I can put in some code but it is a pretty standard UICollectionView with custom cell inside ViewController.
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
NSString *imageName = [NSString stringWithFormat:#"%#", [self.urlArray objectAtIndex:indexPath.row]];
[cell setImageName:imageName];
[cell updateCell];
return cell;
}
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return self.collectionView.frame.size;
}
EDIT:
I just removed the navigation bar and the first 2 images were loading behind the nav bar. They are loading in the size of the default prototype CollectionViewCell. Once I scroll away and back to it, it is the expected size.
When you don't put in constraints, IB automatically puts in constraints for you that give you an absolute position and size based on the frame in the storyboard. Chances are good that the constraints you're adding are not doing what you think they are.
Adding [cell layoutIfNeeded]; right before return cell in cellforitematindexpath fixed it

UICollectionView: issue many cells are selected when I only select one cell

I faced an issue an take lot of time but cannot figure out the issue:
I created a UICollectionView with very simple content, one lable to indicate cell_number, and when a cell is selected, the background of cell is changed to orange.
I create a custom cell with xib file for design (very simple one). And I load this cell from my UICollectionView in my DemoUICVViewController.m file normally as many people did with some steps like:
- declare the custom cell class in ViewDidload:
[self.collectionView registerClass:[MyCustomCell class] forCellWithReuseIdentifier:#"MyCell"];`
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MyCustomCell * myCell = (MyCustomCell*)[cv dequeueReusableCellWithReuseIdentifier:#"myCell" forIndexPath:indexPath];
myCell.lable.text = [arrayNumber objectAtIndex:indexPath.item];
return myCell;
}
and when selected:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
// Get the cellForItemAtIndexPath and set the background coler of cell to orange
}`
Number of section I return 1, and number of item in section I return 10
All the cells in UICollectionView are display correctly. But when I tap to select a cell I see not only that cell is orange, but also some other cells also change to orange for e.g cell 5 and cell 9.
I debug but the didSelectItemAtIndexPath only get called once and at the right index, very strange when some other cells also be orange.
I am not sure if the problem is of Reusability of cell identifier, could someone give me some advise.
I attached photo for e.g here:
Image describes
Finally I found the root cause to fix: add this line to check to
collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
...
if(myCell.selected)
// set background of cell to orange;
else
// set white background;
...
}

UIImageView in UICollectionView cells not displaying

I'm very new to iOS development, sorry for posting such a basic mistake, I just can't get my head around this.
I will tell you what I have done so far, hopefully someone can help me out here. I have not edited any code so far.
Add collection view controller (click and drag into main.storyboard)
Configure cell sizes in the attributes editor of the CollectionView
Drag UIImageView object onto each cell
Import my images into the project (drag images into sidebar and import)
Select each UIImageView and in attributes select the correct image
Having done this, my images display perfectly in the storyboard editor but when I run the app in the simulator it is just a blank screen with my specified background colour.
Screenshot of editor, Screenshot of simulator
You should add the data source method after creating a collection view controller class,
// Defines the number of cells in a section of collection view
- (NSInteger)collectionView:(UICollectionView *)cv numberOfItemsInSection:(NSInteger)section;
{
return numberOfItems;
}
// Defines the cells in the collection view
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{
// Gallerycell is the custom collection view cell class holds the UIImage View
GalleryCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"GalleryCell" forIndexPath:indexPath];
// getting the image
cell.cellImage.image = [UIImage imageNamed:[dataSourceArray objectAtIndex:indexPath.row]];
return cell;
}
You should implement datasource methods for displaying a cell. Doesn't meter if it's static or dynamic cells.

Programmatically setting the height of a UIView subview inside a cell of a UICollectionViewController?

Inside the reusable view of my cell, I have a UIView.
Then, I have this method in the controller
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// .. set value for CGFloat backgroundHeight
[cell addSubview:cell.backgroundView];
CGRect f = cell.backgroundView.frame;
f.size.height = backgroundHeight;
cell.backgroundView.frame = f;
}
But the UIView's height remains the same as specified in the Layout Rectangle.
What should I try next?
Your problem here lies in the fact that you are attempting to use the cell's backgroundView.
Firstly, you cannot add the cell's backgroundView as a subview. You simply assign a UIView to it with :
cell.backgroundView = yourView;
Secondly, if you read the docs, it clearly states :
Use this property to assign a custom background view to the cell. The background view is placed behind the content view and its frame is automatically adjusted so that it fills the bounds of the cell.
This means, no matter what frame you try to set for the backgroundView it will automatically adjust and fill the entire cell. Now, I haven't actually tried it, but you might be able to override this by subclassing. Though, i'll mention here, I am unsure.
Back to your problem, if you really want a UIView that you can control, you will need to create a UIView and then add it as a subview. Using the cell's backgroundView is not the solution.
It just seems like useless, what you'r approaching with the UICollectionViewCell's backgroundView .
By the Doc
backgroundView The view that provides the background appearance.
#property (nonatomic, retain) UIView *backgroundView; Discussion The
view (if any) in this property is positioned underneath all of the
other content and sized automatically to fill the entire bounds of the
collection view. The background view does not scroll with the
collection view’s other content. The collection view maintains a
strong reference to the background view object.
This property is nil by default, which displays the background color
of the collection view.
the backgroundView is just nothing but the cell, so what you'r upto do is doesn't effect . seems like directly changing the Cell's height.
the best solution is to just ignore the backgroundView property all
together. Instead, make the collection view’s background clear, and
implement your own View; just throw a view behind the
collection view.
Kindly check this blog, this would be helpful for you.
You can manage the Layout height With sizeForItemAtIndexPath
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
return CGSizeMake(view.frame.size.width, view.frame.size.height);
}
here you can manage spacing
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
return UIEdgeInsetsMake(5,5,0,5);
}
Controlling UICollectionViewCells is just the same as UITableViewCell. What you need to do is create a UICollectionViewCell subclass. These can seem confusing to start with but are really pretty simple to set up.
The first thing is to add any additional properties you might need like additional UIImageViews, UILabels etc. Now, we need to make sure all objects are instantiated but only once so this happens in
- (id)initWithFrame:(CGRect)frame
As well as instantiating an adding subviews to self.contentView set any global or default properties such as font, color etc. You can't set a frame relative to self.contentView yet though because self.contentView has zero size until layoutSubviews.
Now, create a method:
-(void)layoutSubviews
{
[super layout subviews];
...
[self.backgroundView setFrame: myFrame]; // in this case
}
The [super layoutSubviews] is important to set self.contentView's frame from the delegate cell layout methods. This method is called every time the cell comes into view or changes in any way (which is often). What you need to do now is set the various frames of things based on self.contentView.frame or self.frame. Also, you can set any conditional properties like hiding icons depending on a state etc.
To answer the question, you do not need to add self.backgroundView because it is already there. What you do need to do is set the frame in layoutSubviews as above but you need a UICollectionViewCell subclass in order to do that.
To use the custom cell you just need to include your new .h file and swap UICollectionViewCell for your new classname in the
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
method like:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor redColor];
return cell;
}
Do it like below, as you can not modify only height in frame you have to define new frame using CGRectMake function, after this you will also require to change the cell height also otherwise your view will be displayed in that much portion only.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// .. set value for CGFloat backgroundHeight
[cell addSubview:cell.backgroundView];
CGRect frame = CGRectMake(cell.backgroundView.frame.origin.x, cell.backgroundView.frame.origin.y, cell.backgroundView.frame.size.width, backgroundHeight);
cell.backgroundView.frame = frame;
}

how to set dynamic uicollectionviewcell size from its content - programmatically

I need to have just simple UICollectionViewCell style with cells on top of eachoher. Like tableview. But I need Dynamic height dependent of the content, size the content is comments it can vary.
I got
viewDidLoad:
[self.commentsCollectionView registerClass:[GWCommentsCollectionViewCell class] forCellWithReuseIdentifier:#"commentCell"];
in .h I got:
and I #import my custom UICollectionViewCell that sets all constraints with programmatic autolayout.
I instantiate the UICollectionView with:
UICollectionViewFlowLayout *collViewLayout = [[UICollectionViewFlowLayout alloc]init];
self.commentsCollectionView = [[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:collViewLayout];
I use autolatyout to get the UICollectionView be where I want (thats why CGRectZero).
And finally I was hoping to do this:
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
GWCommentsCollectionViewCell *cell = (GWCommentsCollectionViewCell*)[collectionView cellForItemAtIndexPath:indexPath];
return cell.singleCommentContainerview.bounds.size;
}
singleCommentContainerview is a direct subview of the contentView and withing the singleCommentContainerview I have UILabels, UIImageViews etc, all set witih autolayoutcode.
But I just get cgsize value of (0,0)
How can I fix this to get the proper size I need for each cell?
From what I have read UICollectionView needs the sizes worked out before laying out the cell. So the above method of yours that cell hasn't yet been drawn so it has no size. Also it could be an issue or combined with the issue that the cell is cached/pooled with the same identifier #"commentCell", I tag unique cells with a new identifier and class normally.
My thoughts are to catch the cell before it is drawn, push the size into a dictionary for use later, using:
- (void)collectionView:(UICollectionView *)collectionView
willDisplayCell:(UICollectionViewCell *)cell
forItemAtIndexPath:(NSIndexPath *)indexPath{
GWCommentsCollectionViewCell *cell = (GWCommentsCollectionViewCell*)[collectionView cellForItemAtIndexPath:indexPath];
// Need to add it to the view maybe in order for it the autolayout to happen
[offScreenView addSubView:cell];
[cell setNeedsLayout];
CGSize *cellSize=cell.singleCommentContainerview.bounds.size
NSString *key=[NSString stringWithFormat:#"%li,%li",indexPath.section,indexPath.row];
// cellAtIndexPath is a NSMutableDictionary initialised and allocated elsewhere
[cellAtIndexPath setObject:[NSValue valueWithCGSize:cellSize] forKey:key];
}
Then when you need it use that dictionary based off the key to get the size.
Its not a really super pretty way as its dependent on the views being drawn, autolayout doing its thing before you get the size. And if you are loading images even more it could throw up issues.
Maybe a better way would be to preprogram the sizes. If you have data on the images sizes that may help. Check this article for a really good tutorial (yah programatically no IB):
https://bradbambara.wordpress.com/2014/05/24/getting-started-with-custom-uicollectionview-layouts/
Add
class func size(data: WhateverYourData) -> CGSize { /* calculate size here and retrun it */}
to your custom cell and instead of doing
return cell.singleCommentContainerview.bounds.size
it should be
return GWCommentsCollectionViewCell.size(data)

Resources