I am creating a collectionView whose cells are of different sizes and have different content. I am using a cell prototype for these cells, however, when I am adding more than one cell I get weird UI bugs:
This is what it is supposed to look like
This is what it actually looks like
Code:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
Card *card = [[[usermanager getSelectedUser] getCards] objectAtIndex:indexPath.item];
[card setupLayout];
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
if(cell == nil){
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cardCell" forIndexPath:indexPath];
}
[cell addSubview:card];
cell.clipsToBounds = YES;
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
cell.layer.shadowPath = [[UIBezierPath bezierPathWithRect:cell.bounds] CGPath];
//Add dropshadow
cell.contentView.layer.borderWidth = 1.0f;
cell.contentView.layer.borderColor = [UIColor clearColor].CGColor;
cell.contentView.layer.masksToBounds = YES;
cell.layer.shadowColor = [UIColor blackColor].CGColor;
cell.layer.shadowOffset = CGSizeMake(0, 5.0f);
cell.layer.shadowRadius = 2.0f;
cell.layer.shadowOpacity = 0.5f;
cell.layer.masksToBounds = NO;
cell.layer.borderColor = [UIColor yellowColor].CGColor;
cell.layer.borderWidth = 2.0f;
return cell;
}
It propably has something to do with the fact that I use the reusable cell. Because when I create 2 different prototypes in my storyboard for these cells they have no problems at all. Can anyone help me? Thanks
as you say: your cells will be reused, so if you change any layout or frame or colour these properties will be like you set when the cell will be used the next time. you should subclass UICollectionViewCell and implement the method prepareForReuse where you have to reset all views and properties of the cell to the original values and you have to remove the subview card:
-(void)prepareForReuse {
[super prepareForReuse];
// Reset all, for example backgroundView
self.backgroundView = nil;
}
one more point: why you call UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath]; Thats not correct. You need only UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cardCell" forIndexPath:indexPath];
Related
I have an UITableView with UITableViewCell and I want to make cell.imageViewas circles. So I did this in my cellForrowAtIndex
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:simpleTableIdentifier];
}
cell.backgroundColor=[UIColor clearColor];
cell.imageView.layer.cornerRadius=cell.imageView.frame.size.width/2;
cell.imageView.layer.masksToBounds=YES;
cell.imageView.layer.borderWidth = 2.0f;
cell.imageView.layer.borderColor=[UIColor whiteColor].CGColor;
But when load the table UIImages are squares and then when I scroll it become circles. How can I solve this problem?
Please help me.
Thanks
Below is the code
[cell.imgview setImage:[UIImage imageWithData:imgData]];
cell.imgview.layer.cornerRadius = cell.img_userpic.frame.size.height /2;
cell.imgview.layer.masksToBounds = YES;
cell.imgview.layer.borderWidth = 0;
Your Imageview's width and height should be same otherwise it won't display circle.
You need to create a custom cell by inheriting UITableViewCell and then configure cell in that class.
Implement awakeFromNib method in it and set your image view as you need in this method.
Use below line of code in your cellForRow Method. For circle you have to set cornerradius of layer and set clipsToBounds property to YES.
cell.imageView.clipsToBounds = YES;
try this code
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(-30, 40, 100, 100)];
imageView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
imageView.layer.masksToBounds = YES;
imageView.layer.cornerRadius = 50.0;
imageView.layer.shadowRadius=5;
imageView.layer.shadowOpacity=4;
imageView.layer.shadowColor=(__bridge CGColorRef)([UIColor blackColor]);
imageView.layer.borderColor = [UIColor whiteColor].CGColor;
imageView.layer.borderWidth = 3.0f;
imageView.layer.rasterizationScale = [UIScreen mainScreen].scale;
imageView.layer.shouldRasterize = YES;
imageView.clipsToBounds = YES;
I am trying to create multiple collectionViewCells with 4 different types. And every cell has a different view of one of those 4 types. Every view of those types can have different contents based on user selection.
The problem I am having is the fact that some of the cards are overlapping/not loading correctly when multiple views/cells of the same type are on the screen.
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
Card *card = [[[usermanager getSelectedUser] getCards] objectAtIndex:indexPath.item];
NSLog(#"CARD LOADING: %#", card.title);
[card setupLayout];
UICollectionViewCell *cell;
if(card.type.intValue == 1){
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"lifestyleCell" forIndexPath:indexPath];
}else if(card.type.intValue == 2){
cell= [collectionView dequeueReusableCellWithReuseIdentifier:#"sceneCell" forIndexPath:indexPath];
}else if(card.type.intValue == 3){
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"energyCell" forIndexPath:indexPath];
}else if(card.type.intValue == 4){
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"productCell" forIndexPath:indexPath];
}else{
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cardCell" forIndexPath:indexPath];
}
[cell addSubview:card];
//Add dropshadow
cell.contentView.layer.borderWidth = 1.0f;
cell.contentView.layer.borderColor = [UIColor clearColor].CGColor;
cell.contentView.layer.masksToBounds = YES;
cell.layer.shadowColor = [UIColor blackColor].CGColor;
cell.layer.shadowOffset = CGSizeMake(0, 5.0f);
cell.layer.shadowRadius = 2.0f;
cell.layer.shadowOpacity = 0.5f;
cell.layer.masksToBounds = NO;
return cell;
}
The card is the view I add to the cell. As mentioned above there are multiple types of those cards.
try using:
cell.clipsToBounds = YES;
As you scroll a UICollectionView, cells that disappear offscreen are re-used for the new cells coming on-screen. That means if you add subviews in your collectionView:cellForItemAtIndexPath: method, they will still be part of the cell's view hierarchy when that cell is re-used. Every time the cell is re-used, it will add a new subview when you call [cell addSubview:card]. Your card subviews will simply stack on top of each other.
It seems that you're using a collection of Card objects, custom UIView subclasses, to store each user's deck of cards. I would suggest instead that you separate out the model from the view - store each card as a simple data model which represents the card independently of how it is displayed (see MVC). Then you can create a custom UICollectionViewCell subclass which can display any card. In your collectionView:cellForItemAtIndexPath: you would simply reconfigure the cell's view according to the corresponding card data. That way you do not need to call addSubview: within your collectionView:cellForItemAtIndexPath: method.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
//NSLog(#"enter category cell");
CategoryViewCell* cell = (CategoryViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
[cell.imgCat setImage:[UIImage imageNamed:[categoryImages objectAtIndex:indexPath.row]]];
[cell.labelCatName setText:[[NSString stringWithFormat:#"%#", [catName objectAtIndex:indexPath.row]] capitalizedString]];
if([categories[[NSString stringWithFormat:#"%d",(int)indexPath.row]] isEqual:#YES]) {
//NSLog(#"set border");
cell.layer.borderColor = [UIColor redColor].CGColor;
cell.layer.borderWidth = 3;
}
return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
CategoryViewCell* cell = (CategoryViewCell*)[collectionView cellForItemAtIndexPath:indexPath];
cell.layer.borderWidth = 3;
cell.layer.borderColor = [UIColor redColor].CGColor;
//NSLog(#"%i", (int)indexPath.item);
categories[[NSString stringWithFormat:#"%i", (int)indexPath.item]] = #YES;
}
-(void) collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
CategoryViewCell* cell = (CategoryViewCell*)[collectionView cellForItemAtIndexPath:indexPath];
cell.layer.borderColor = [UIColor clearColor].CGColor;
categories[[NSString stringWithFormat:#"%i", (int)indexPath.item]] = #NO;
}
The problem:
The above code will show you a collectionView with cells that are selected at default. However, the states of these selected cells are not selected. So I have to tap twice to deselect them because the first tap is to select them, and second tap is to deselect them.
I have tried to set selected for cell but it doesn't work either. The cell will have a red border whenever the user selected a cell and clearColor when the user deselect the cell.
I tried:
cell.selected = YES;
But this permanently gives a collectionView Cell a red border.
And add it in cellForItemAtIndexPath method still doesn't do the trick.
[self collectionView:collectionView didSelectItemAtIndexPath:indexPath];
CategoryViewCell.m
-(void) setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected];
//NSLog(#"Pass Select Animated");
if (selected) {
self.flagHighlight = NO;
self.selected = NO;
self.layer.borderColor = [UIColor clearColor].CGColor;
self.layer.borderWidth = 3;
} else {
self.flagHighlight = YES;
self.selected = YES;
self.layer.borderColor = [UIColor redColor].CGColor;
self.layer.borderWidth = 3;
}
}
How would I pre-select a cell when the view is loaded programmatically?
Or even better just change the state of the cell being selected.
Thanks in advance.
Ending up answering my own problem.
so I use [collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone];
in cellForItemAtIndexPath.
Serve the purpose nicely.
I am using a CollectionView to display an image in. I am using horizontal scrolling with pagination enabled so the user is able to scroll from image to image right to left as they would on the apps screen on iOS. How might I be able to call didSelectItemAtIndexPath to detect which cell the collection view has stopped on without the user having to tap on the cell?
Though it is not relevant:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
titleLabel.alpha = 1.0;
mainTextLabel.alpha = 1.0;
availableLabel.alpha = 1.0;
sizeLabel.alpha = 0.0;
sizeImage.alpha = 0.0;
moreInfoOnSize.alpha = 0.0;
UICollectionViewCell *datasetCell =[collectionView cellForItemAtIndexPath:indexPath];
datasetCell.backgroundColor = [UIColor lightGrayColor]; // highlight selection
PFObject *selectedObject = [labelFileArray objectAtIndex:indexPath.row];
titleLabel.text = selectedObject[#"labelText"];
PFObject *selectedObject2 = [mainTextArray objectAtIndex:indexPath.row];
mainTextLabel.text = selectedObject[#"mainTextLabel"];
PFObject *selectedObject3 = [availableLabelArray objectAtIndex:indexPath.row];
availableLabel.text = selectedObject[#"availableLabel"];
if ([availableLabel.text isEqual:#"Available"]) {
availableLabel.backgroundColor = [UIColor greenColor];
} else if ([availableLabel.text isEqual:#"Sorry We Are Out!"])
{
availableLabel.backgroundColor = [UIColor redColor];
}
NSLog(#"%#", indexPath);
}
And Image
http://cl.ly/image/3x1R41073W2z
http://cl.ly/image/203Q2E3T2X44
Thank you so much!
You can call visibleCells on your collection view to get the cells currently visible on the screen like this:
// All visible cells (1 or more depending on your layout and cell sizes)
NSArray *visibleCells = [myCollectionView visibleCells];
// Get the first cell from the array
UICollectionViewCell *firstCell = visibleCells.firstObject;
I need to make the background of only one UITableViewCell fully transparent for iOS7 / iOS6.
What I did:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ButtonsCell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor clearColor];
cell.backgroundView = [UIView new];
cell.selectedBackgroundView = [UIView new];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
What I get:
in iOS6 everything is OK:
but in iOS7 there are two horizontal grey lines:
Is it possible to remove them?..
tableView.separatorColor = [UIColor clearColor];