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
Related
In my project i have collection ,in which horizontal pagination is enabled, Every thing working fine but, when i scroll,particular cell item not fit entire cell,It show half image of previous cell item and half current Items, i need One item to fit the entire screen ??? Any suggestion are welcome
Here is the code:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath; {
SingleItemCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"SingleItemCollectionViewCell" forIndexPath:indexPath];
[cell ConfigaureCollectionViewItem:self.totalCellItems[indexPath.row]]; return cell;
}
-(CGSize)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGSize size = CGSizeMake(self.bounds.size.width - 20, self.bounds.size.height - 40);
return size;
}
Perhaps you should be using UIPageViewController in stead of UICollectionView. From your question it seems that you are trying to mimic the behaviour of the former.
I think that sorry does not speak English well .
I want 4-way scroll. It was constructed as follows.
RootCollection View has vertical scroll.
ChildCollection View has horizontal scroll.
It looks working well. but it has problem.
And once on the first page , scroll to the right.
The vertical scroll twice .
Scroll has already gotta go to the right page .
I think UICollectionview has ReusableCell mechanism.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"mainCustomCell" forIndexPath:indexPath];
[cell.collectionView reloadData];
[cell.collectionView setContentOffset:CGPointZero animated:NO];
return cell;
}
i recoded simulator
http://pass2phone.com/files/masse_test.mov
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
I am using a UICollectionView. Inside this View one of my cells has a size of 1000*600(showing one cell in screen).
In my UICollectionViewCell are 4 UILabels and two tableViews.
The data which I am passing to UILabels is not showing correctly and as soon as I scroll back the data does not retain. I have seen various example in which it was suggested to use block Operation.
Which approach I have to use? Please help.
Here is the code:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
ToursCollectionViewCell *collectionViewCell=[collectionView dequeueReusableCellWithReuseIdentifier:#"collectionViewCell" forIndexPath:indexPath ];
UILabel *artistOne=(UILabel*)[self.collectionView viewWithTag:1111];
artistOne.text=[artistNameOneArray objectAtIndex:indexPath.row];
UILabel *venueOne=(UILabel*)[self.collectionView viewWithTag:1212];
venueOne.text=[venueLocationOneArray objectAtIndex: indexPath.row];
UILabel *artistTwo=(UILabel*)[self.collectionView viewWithTag:2121];
artistTwo.text=[artistNameTwoArray objectAtIndex:indexPath.row];
UILabel *venueTwo=(UILabel*)[self.collectionView viewWithTag:2222];
venueTwo.text=[venueLocationTwoArray objectAtIndex:indexPath.row];
return collectionViewCell;
}
UILabel *artistOne=(UILabel*)[self.collectionView viewWithTag:1111];
should probably be
UILabel *artistOne=(UILabel*)[collectionViewCell viewWithTag:1111];
(and similarly for the other labels) because the labels are subviews of each
individual cell and not of the entire collection view.
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)