F0nt4z F0nt4z - 1 month ago 9
iOS Question

UICollectionView displays wrong cell order after scrolling

My problem is the following:
I created a UICollectionViewController that should display previous downloaded text-content in separate custom cells (see attached screenshots). But after scrolling down, the cells are not in the same order anymore. I also checked, the indexpath... I think that the App returns the wrong cells to the wrong index path.row


After launching

After scrolling [Wrong Content AND Wrong Order]


Heres my code for the

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

TextCollectionViewCell *textCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"textCell" forIndexPath:indexPath];
//CURRENT DATA
NSLog(@"Row: %li - Item:%li",(long)indexPath.row,(long)indexPath.item);
NSDictionary *currentDataDict = nil;
currentDataDict = [[_feedItemsArray objectAtIndex:indexPath.item]copy];
NSLog(@"%@",[currentDataDict valueForKey:@"id"]);
if ([textCell.subviews count] <=2) {
[textCell initCell:[currentDataDict valueForKey:@"text"] time:NULL username:[currentDataDict valueForKey:@"admin"]];
}
[textCell.btn_title addTarget:self
action:@selector(goToProfile)
forControlEvents:UIControlEventTouchUpInside];

return textCell;
}


And the Subclass function

-(void)initCell:(NSString*)content time:(NSDate*)time username:(NSString*)username` in the `TextCollectionViewCell`-Class:

self.backgroundColor = [UIColor clearColor];


UIImageView *profileImg = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width*0.13, self.frame.size.width*0.13)];
profileImg.image = [UIImage imageNamed:@"prfImg.png"];
profileImg.layer.cornerRadius = profileImg.frame.size.height /2;
profileImg.layer.masksToBounds = YES;
profileImg.layer.borderWidth = 3;
profileImg.layer.borderColor = [UIColor whiteColor].CGColor;


self.btn_title = [[UIButton alloc]initWithFrame:CGRectMake(50, 2, self.frame.size.width*0.5, self.frame.size.height *0.1)];
[self.btn_title setTitle: [NSString stringWithFormat:@"@%@",username] forState:UIControlStateNormal];
[self.btn_title setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
[self.btn_title setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

// [lbl_title setFont:[UIFont fontWithName:@"Helvetica Neue-CondensedBold" size:14]];


UILabel *lbl_time = [[UILabel alloc]initWithFrame:CGRectMake(50, 20, self.frame.size.width*0.5, self.frame.size.height *0.1)];
lbl_time.text = @"Gerade eben";
[lbl_time setFont:[UIFont systemFontOfSize:12]];
lbl_time.textColor = [UIColor grayColor];

self.lbl_main = [[UILabel alloc]initWithFrame:CGRectMake(0, 50, self.frame.size.width, self.frame.size.height*0.7)];
//Calculate the expected size based on the font and linebreak mode of your label
// FLT_MAX here simply means no constraint in height
self.lbl_main.font = [UIFont fontWithName:@"Helvetica" size:15.0];
[self.lbl_main setPreferredMaxLayoutWidth:280.0];
self.lbl_main.numberOfLines = 0;
CGSize maximumLabelSize = CGSizeMake(self.frame.size.width, self.frame.size.height);

CGSize expectedLabelSize = [content sizeWithFont:self.lbl_main.font constrainedToSize:maximumLabelSize lineBreakMode:self.lbl_main.lineBreakMode];
//adjust the label the the new height.
float height = lbl_time.frame.origin.y+lbl_time.frame.size.height;
CGRect newFrame = CGRectMake(self.frame.size.width*0.1, height , self.frame.size.width*0.85, self.frame.size.height*0.6);
self.lbl_main.frame = newFrame;
self.lbl_main.text = content;
self.lbl_main.textColor = [UIColor whiteColor];
//lbl_main.backgroundColor = [UIColor redColor];
float heightBTN = self.frame.size.width*0.16;

self.cont_text = [[UIView alloc]initWithFrame:CGRectMake(0, 50, self.frame.size.width, self.frame.size.height-heightBTN-50)];
self.cont_text.backgroundColor = [UIColor colorWithRed:0.86 green:0.32 blue:0.13 alpha:1.0];
self.cont_text.layer.cornerRadius = 8;
self.cont_text.layer.masksToBounds = YES;
self.lbl_main.center = CGPointMake(self.cont_text.frame.size.width*0.5, self.cont_text.frame.size.height*0.5);

float btnX = self.frame.size.width-heightBTN*1.1;
float btnY = self.cont_text.frame.size.height+self.cont_text.frame.origin.y*0.5;

UIButton *btn_like = [[UIButton alloc]initWithFrame:CGRectMake(btnX,btnY,heightBTN , heightBTN)];
[btn_like.layer setMasksToBounds:YES];
[btn_like.layer setCornerRadius:heightBTN*0.5];
btn_like.backgroundColor = [UIColor colorWithRed:1.00 green:0.69 blue:0.23 alpha:1.0];

UIImageView *img_like = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, btn_like.frame.size.width*0.5, btn_like.frame.size.width*0.5)];
img_like.image = [UIImage imageNamed:@"like.png"];
img_like.center = CGPointMake(btn_like.frame.size.width*0.5, btn_like.frame.size.height*0.5);
[btn_like addSubview:img_like];
NSLog(@"%@",self.subviews);
if ([self.subviews count] <=2) {
[self addSubview:self.cont_text];
[self addSubview:btn_like];
[self addSubview:lbl_time];
[self addSubview:self.btn_title];
[self addSubview:profileImg];
[self.cont_text addSubview:self.lbl_main];

}

}


Can somebody help me?

Answer

In the cell designated initWithFrame write the code in your

-(void)initCell:(NSString*)content time:(NSDate*)time username:(NSString*)username

This will initialize the cell with the subviews, you need without calling your above mentioned custom method. Also create properties for the subviews.

The way you have named the method and intend to use it is also confusing and wrong. After that I would suggest in:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

clear out the content of each subview by using the properties of the cell. Then add the content you wish from the dictionary. Hope this helps

Comments