I've set up a Collection View in my storyboard and set its delegate and data source to the view controller, put an ImageView inside of a cell, and have even changed the background of it, but I can't get it to show an image. I've tried adding a button to reload the data, but when I click it nothing happens so I don't think the image is even being passed.
I made sure that my cell and image view has an identifier and I'm using the following code to try to populate the collection view:
View.h file:
__weak IBOutlet UICollectionView *CollectionView;
View.m file
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
UIImageView *imageView = (UIImageView *)[cell viewWithTag:302];
UIImage * image = [UIImage imageNamed:#"sunset.jpeg"];
[imageView setImage:image];
return cell;
}
Related
I am using collectionView in my app.
I have label inside my collectionViewCell.
I want to set frame to that label.
My code is:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath; {
menuCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
cell.lblTag.frame = cell.contentView.frame;
cell.lblTag.text = [arrMenu objectAtIndex:indexPath.row];
return cell;
}
But this frame is works after i scroll collection view.
how can i reload collection view so that label frame set when collectionView display.
you can reload the collection view in viewDidAppear
-(void)viewDidAppear:(BOOL)animated
{
[self.yourcollectionView_outLet reloadData];
}
in my case it work for me.
you can try to change frame in main queue
dispatch_async(dispatch_get_main_queue(), ^{
cell.lblTag.frame = cell.contentView.frame;
});
i am working on my application in which I have to add an image to collection view cell on selection. Collection view cell is circular and filled with color, so on selection of cell, image of tick should be on that color.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
NSArray *hexaColor= _advantageModelObj.productDetail.carColorDetails;
CarColorDetailObject *carColor= [hexaColor objectAtIndex:indexPath.row];
NSString *hexCode= carColor.carColor.hexCode;
cell.layer.masksToBounds=TRUE;
cell.backgroundColor=[self colorWithHexString:hexCode];
cell.layer.cornerRadius= (roundf(cell.frame.size.width/2));
cell.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:#"colorselected.png"]];
return cell;
}
Make global variable
int clickedIndex;
2 in viewDidLoad assign to clickedIndex
clickedIndex=-1;
in collectionView didSelectItemAtIndexPath
clickedIndex=(int)indexPath.row;
[collectionView reloadData];
4 add some line in collectionView cellForItemAtIndexPath
if(clickedIndex==indexPath.row){
UIImageView* imageView=[[UIImageView alloc]init];
[imageView setFrame:CGRectMake(10, 0, cell.contentView.size.width, cell.contentView.size.height)];
imageView.image=[UIImage imageNamed:[NSString stringWithFormat:#“tickImage”,]];
imageView.alpha=0.5;
[cell.contentView addSubview: imageView];
}
I am able to load Images in UICollectionView, using following code, but the problem is, It will load images after the screen is Scrolled. Without Scroll it will just display only Empty Cells.
Note:- I am not loading images from any link(API), It is from images.xcassets file or supporting Files.
Here is code for UICollectionView:
#import "ViewController.h"
#interface ViewController()
#end
#implementation ViewController
-(void)viewDidLoad {
[super viewDidLoad];
collectionImages = [NSArray arrayWithObjects:#"car1.jpeg",#"car2.jpeg",#"car3.jpeg",#"car4.jpeg",#"car5.jpeg",#"car6.jpeg", nil];
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return collectionImages.count;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier =#"Cell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
UIImageView * collectionImageView = (UIImageView *) [cell viewWithTag:100];
collectionImageView.image = [UIImage imageNamed:[collectionImages objectAtIndex:indexPath.item]];
return cell;
}
#end
Following Image, When I run program but without scrolling.If I scroll, it will load image one-by one.
call
[collectionImageView reloadData]
at
- (void)viewWillAppear:(BOOL)animated
I am using collectionView in my App. I am setting image for the cell backgroundView in didSelect delegate. But When i select one cell indexPath the image is getting set for 3 cell indexPath. When i scroll the collectionView the images are getting changed randomly? Please Help me. thanks in advance.
- (void)viewDidLoad
{
[super viewDidLoad];
[collection registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:uio];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection: (NSInteger)section
{
return 50;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collection dequeueReusableCellWithReuseIdentifier:uio
forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"index %#",indexPath);
UICollectionViewCell *cell = [collection cellForItemAtIndexPath:indexPath];
cell.backgroundView =[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"download.jpg"]];
}
That's because you reuse your cell. An option would be to have an dictionary variable to say that your cell has been selected and reset the image if it has not been.
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"index %#",indexPath);
UICollectionViewCell *cell = [collection cellForItemAtIndexPath:indexPath];
cell.backgroundView =[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"download.jpg"]];
[selectedDictionary setObject:[NSNumber numberWithBool:YES] forKey:[NSNumber numberWithInteger:indexPath.row]];
}
Then in your cellForItemAtIndexPath method you would check that value
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collection dequeueReusableCellWithReuseIdentifier:uio
forIndexPath:indexPath];
BOOL selected = [[selectedDictionary objectForKey:[NSNumber numberWithInteger:indexPath.row]] boolValue];
if(selected){
cell.backgroundView =[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"download.jpg"]];
}else{
cell.backgroundView = nil;
}
cell.backgroundColor = [UIColor whiteColor];
return cell;
}
Of course if you use some kind of object as model, it would appropriate to have a selected variable in here, you won't need a nsdictionary any more.
The Problem is dequeueReusableCellWithReuseIdentifier.
When you scroll UICollectionview then cell are reused that is problem
add Collectionview inside scrollview.
Try this Inside:
Scroll_View is Your Scroll View
collection is Your Collectionview
-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
self.Scroll_View.contentSize = CGSizeMake(self.view.frame.size.width, collectionView.contentSize.height);
CGRect fram_For_Collection_View = self.collection_view.frame;
fram_For_Collection_View.size.height = collectionView.contentSize.height;
self.collection.view.frame = fram_For_Collection_View;
}
Your -collectionView:didSelectItemAtPath: is adding a new image view to the cell. Nothing is removing that image view when the cell is reused. So, when you say:
UICollectionViewCell *cell = [collection dequeueReusableCellWithReuseIdentifier:uio
forIndexPath:indexPath];
in your -collectionView:cellForItemAtIndexPath:, you're may get back some cell that already has one or more image views.
My suggestion would be to add the image view to the cell in the cell prototype, perhaps in your storyboard or in the cell's initializer. Have your -collectionView:cellForItemAtIndexPath: set the image for that image view to the correct image for the given path.
What's happening is that UICollectionView reuses cells. So in didSelectItemAtIndexPath: you set the cell background, but then the UICollectionView reuses that same cell as needed (and you're not resetting the cell.backgroundView in cellForItemAtIndexPath:).
The way to fix this is to maintain an NSIndexSet of selected cells. In didSelectItemAtIndexPath: you can add the index of the item that was selected, and then force a reload of that item by calling reloadItemsAtIndexPaths. Then, in your cellForItemAtIndexPath: check the index set to see if the selected index is included, and if so, set the backgroundView of the cell.
I had the same issue few days ago & I posted a question here. Here is the answer I got & it works for me.
Collection View Cell multiple item select Error
And also if you are using a custom cell you can add this code to the init method of that cell & it will work too.
CGFloat borderWidth = 6.0f;
UIView *bgView = [[UIView alloc] initWithFrame:frame];
bgView.layer.borderColor = [UIColor redColor].CGColor;
bgView.layer.borderWidth = borderWidth;
self.selectedBackgroundView = bgView;
I have a UICollectionViewCell subclass called AlbumCVC that contains a single IBOutlet --- a UIImageView called cellView. I'm setting the value of cellView for each cell inside the following method:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell;
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"albumPhotoCell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor blueColor];
if ([cell isKindOfClass:[AlbumCVC class]]){
AlbumCVC *albumCVC = (AlbumCVC *)cell;
ALAsset *thisImage = [self.albumPhotos objectAtIndex:indexPath.item];
albumCVC.imageView.frame = albumCVC.contentView.frame;
albumCVC.contentView.contentMode = UIViewContentModeScaleAspectFit;
albumCVC.imageView.image = [UIImage imageWithCGImage:[thisImage aspectRatioThumbnail]];
}
}
return cell;
}
where albumPhotos is an NSMutableArray of ALAssets. I'm sure that the property is getting set correctly because I get sensible results when I log the albumCVC.cellImage.image.bounds.size. Cells are also sized properly as the frames are visible when I set the background color. But for some reason, cellImage won't display. Is there another method call I need to make inside collectionView:cellForItemAtIndexPath: in order to get the image to show up?
Update: On the advice of a very smart friend, I tried moving the UIImageView out of the cell, putting it elsewhere in the main view, and everything worked lovely. The problem appears to have something to do with the frame / bounds of the UIImageView. I think there's a method call I need to make so that the cell's subview expands to fit the newly-resized cell following the call to collectionView:layout:sizeForItemAtIndexPath:. The problem now is that UIImageView.image.size is a read-only property, so I can't resize it directly.
Update 2: On another piece of advice I looked at the frame and bounds of the cell's contentView and cellImage and found that they weren't matching up. Added another method call to make them equal, and even changed contentMode to UIViewContentModeScaleAspectFit in order to try and get the cell to render the thumbnail properly. Unfortunately, I'm still getting tiny thumbnails inside huge cells. Any idea why? Updated code above and below.
For the sake of completeness, here's the entire class implementation:
#import "AlbumViewController.h"
#import "AlbumCVC.h"
#import <AssetsLibrary/AssetsLibrary.h>
#interface AlbumViewController ()
#end
#implementation AlbumViewController
#pragma constants
const int IPHONE_WIDTH = 320;
#pragma delegate methods
- (NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section{
// Get the count of photos in album at index albumIndex in the PhotoHandler
NSInteger numCells = [self.group numberOfAssets];
return numCells;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell;
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"albumPhotoCell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor blueColor];
if ([cell isKindOfClass:[AlbumCVC class]]){
AlbumCVC *albumCVC = (AlbumCVC *)cell;
ALAsset *thisImage = [self.albumPhotos objectAtIndex:indexPath.item];
}
albumCVC.imageView.frame = albumCVC.contentView.frame;
albumCVC.contentView.contentMode = UIViewContentModeScaleAspectFit;
albumCVC.imageView.image = [UIImage imageWithCGImage:[thisImage aspectRatioThumbnail]];
}
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
//Copy a pointer to an asset from the album
ALAsset *thisImage = [self.albumPhotos objectAtIndex:indexPath.item]; //Zen - are you sure thisImage represents a valid image?
//Copy that asset's size and create a new size struct
CGSize thisSize = thisImage.defaultRepresentation.dimensions;
CGSize returnSize;
// force all previews to be full width
returnSize.width = IPHONE_WIDTH;
returnSize.height = IPHONE_WIDTH * thisSize.height / thisSize.width;
return returnSize;
}
#pragma lifecycle methods
- (void)viewWillAppear:(BOOL)animated{
[self.albumPhotos removeAllObjects];
//"handler" is a class that manages calls to the ALAssetLibrary. self.albumIndex is an integer that gets set on segue. As far as I can tell, everything in the below method is working fine --- cells are sized properly.
self.group = self.albumDelegate.handler.groups[self.albumIndex];
[self.group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
if (result) {
NSLog(#"Just added an object to albumPhotos.");
[self.albumPhotos addObject:result];
NSLog(#"The item in albumPhotos is class %#", [self.albumPhotos[0] class]);
}
}];
}
#pragma instantiation
- (ALAssetsGroup *)group{
if (!_group) {
_group = [[ALAssetsGroup alloc]init];
}
return _group;
}
- (NSMutableArray *)albumPhotos{
if (!_albumPhotos) {
_albumPhotos = [[NSMutableArray alloc]init];
}
return _albumPhotos;
}
#end
Update 3: I can't be certain what the problem was initially, but I know that it now works with the following cellForItem implementation:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell;
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"albumPhotoCell" forIndexPath:indexPath];
if ([cell isKindOfClass:[AlbumCVC class]]) {
AlbumCVC *albumCVC = (AlbumCVC *)cell;
albumCVC.albumImageView.image = [[UIImage alloc] initWithCGImage:[self.albumAssets[[self reverseAlbumIndexForIndex:indexPath.item]] thumbnail]];
}
cell.alpha = [self alphaForSelected:self.selectedItems[#(indexPath.item)]];
return cell;
}
There's no screwing around with frames or bounds anywhere, everything just works. Maybe it's the difference between [[UIImage alloc]initWithCGImage] and [UIImage imageWithCGImage]?
I've had a similar issue and resolved it by setting the UICollectionViewCell frame property to be the same as the UIImageView's frame. I'm not 100% sure that this is your issue, I was building the collection purely in code (no Storyboard)