I am having a UITableViewCell which is displaying data from a JSON Array consisting of Instagram Pictures. However the UITableViewCell is messed up in the sense that each corresponding Cell has the prior Cells data on top of it. Its more of a UI issue rather than actual web API issue. This issue can best be shown in a picture so I have provided one below Here is the code I am using:
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"InstaCell"];
cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"Background.png"]];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"InstaCell"];
}
NSDictionary *entry = instaPics[indexPath.row];
//
// SETUP VIEWS
//
// Name
self.nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(73, 6, 192, 25)];
[self.nameLabel setFont:[UIFont fontWithName:@"Helvetica-Regular" size:16.0]];
// Profile Pic
self.profilePic = [[UIImageView alloc] initWithFrame:CGRectMake(10, 6, 50, 50)];
// Date Label
self.dateLabel = [[UILabel alloc] initWithFrame:CGRectMake(68, 29, 192, 21)];
[self.dateLabel setFont:[UIFont fontWithName:@"Helvetica-Light" size:12.0]];
// Like Button
self.likeButton = [[UIButton alloc] initWithFrame:CGRectMake(68, 279, 18, 18)];
[self.likeButton setBackgroundImage:[UIImage imageNamed:@"heartShape.png"] forState:UIControlStateNormal];
[self.likeButton addTarget:self action:@selector(didTapLikeButton:) forControlEvents:UIControlEventTouchUpInside];
// Comment Button
self.commentButton = [[UIButton alloc] initWithFrame:CGRectMake(68, 29, 192, 21)];
// Like Label
self.likeLabel = [[UILabel alloc] initWithFrame:CGRectMake(40, 371, 50, 21)];
self.likeLabel.font = [UIFont fontWithName:@"HelveticaNeue-Medium" size:14];
self.likeLabel.textColor = [UIColor orangeColor];
// Heart Icon
self.heartIcon = [[UIButton alloc] initWithFrame:CGRectMake(20, 375, 14, 14)];
[self.heartIcon setBackgroundImage:[UIImage imageNamed:@"heart.png"] forState:UIControlStateNormal];
[self.heartIcon setTitleColor:[UIColor grayColor]
forState:UIControlStateHighlighted];
[self.heartIcon addTarget:self action:@selector(didTapLikeIcon:) forControlEvents:UIControlEventTouchUpInside];
// Comment Icon
self.commentIcon = [[UIButton alloc] initWithFrame:CGRectMake(20, 395, 14, 14)];
[self.commentIcon setBackgroundImage:[UIImage imageNamed:@"comment.png"] forState:UIControlStateNormal];
[self.commentIcon setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
[self.commentIcon addTarget:self action:@selector(didTapCommentIcon:) forControlEvents:UIControlEventTouchUpInside];
// Comment Text
self.commentText = [[UILabel alloc] initWithFrame:CGRectMake(-88, 370, 259, 40)];
[[self.commentText layer] setAnchorPoint:CGPointMake(0, 0)];
self.commentText.font = [UIFont fontWithName:@"HelveticaNeue" size:14];
self.commentText.lineBreakMode = NSLineBreakByWordWrapping;
self.commentText.numberOfLines = 3;
self.commentText.textColor = [UIColor blackColor];
// Location Icon
self.locationIcon = [[UIButton alloc] initWithFrame:CGRectMake(73, 33, 12, 12)];
[self.locationIcon setBackgroundImage:[UIImage imageNamed:@"location.png"] forState:UIControlStateNormal];
[self.locationIcon setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
[self.locationIcon addTarget:self action:@selector(didTapLocationIcon:) forControlEvents:UIControlEventTouchUpInside];
// Heart Button
self.heartButton = [[UIButton alloc] initWithFrame:CGRectMake(40, 465, 25, 25)];
[self.heartButton setBackgroundImage:[UIImage imageNamed:@"heart.png"] forState:UIControlStateNormal];
[self.heartButton setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
// Comment Button
self.commentButton = [[UIButton alloc] initWithFrame:CGRectMake(220, 465, 25, 25 )];
[self.commentButton setBackgroundImage:[UIImage imageNamed:@"comment.png"] forState:UIControlStateNormal];
[self.commentButton setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
//
// ADD DATA
//
// Set User Name
NSString *user = entry[@"user"][@"full_name"];
[self.nameLabel setText:user];
// If no Caption
if (entry[@"caption"] != [NSNull null] && entry[@"caption"][@"text"] != [NSNull null]) {
NSString *caption = entry[@"caption"][@"text"];
[self.commentText setText:caption];
}else{
NSString *caption = @"";
[self.commentText setText:caption];
}
// Set the number of likes
NSString *likesCount = entry[@"likes"][@"count"];
NSString *likes = [NSString stringWithFormat: @"%@", likesCount];
[self.likeLabel setText:likes];
// Add Profile Image
NSURL *imageUrl = entry[@"user"][@"profile_picture"];
[self.profilePic sd_setImageWithURL:imageUrl completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
self.profilePic.image = image;
//Make the Profile Pic ImageView Circular
CALayer *imageLayer = self.profilePic.layer;
[imageLayer setCornerRadius:25];
[imageLayer setMasksToBounds:YES];
}];
//NSString *latitude = entry[@"location"][@"latitude"];
//NSString *longitude = entry[@"location"][@"longitude"];
//if ([[entry objectForKey:@"location"] objectForKey:@"latitude"] == NSNotFound) {
// NSLog(@"Contains Location");
//}
[self.commentButton addTarget:self action:@selector(commentButtonTap:) forControlEvents:UIControlEventTouchUpInside];
[self.likeButton addTarget:self action:@selector(likeButtonTap:) forControlEvents:UIControlEventTouchUpInside];
NSDictionary *instapic = [self.instaPics objectAtIndex:indexPath.row];
// Comparator to determine if their are any videos availible
if (entry[@"videos"] != nil) {
// Set Videos
NSLog(@"there are videos: %@", entry[@"videos"]);
CGFloat width = [UIScreen mainScreen].bounds.size.width;
_playerView = [[GUIPlayerView alloc] initWithFrame:CGRectMake(10, 65, 299, 299)];
[_playerView setDelegate:self];
[[self view] addSubview:_playerView];
NSString *urlstring = entry[@"videos"][@"standard_resolution"][@"url"];
NSURL *URL = [NSURL URLWithString:urlstring];
[_playerView setVideoURL:URL];
[_playerView prepareAndPlayAutomatically:YES];
}else{
// Set Image
self.instagramPic = [[UIImageView alloc] initWithFrame:CGRectMake(10, 65, 299, 299)];
NSString *imageUrlString = entry[@"images"][@"low_resolution"][@"url"];
NSURL *url = [NSURL URLWithString:imageUrlString];
[self.instagramPic sd_setImageWithURL:url];
}
//
// ADD ALL SUBVIEWS
//
[cell addSubview:self.commentButton];
[cell addSubview:self.nameLabel];
[cell addSubview:self.profilePic];
[cell addSubview:self.instagramPic];
[cell addSubview:self.dateLabel];
[cell addSubview:self.likeButton];
[cell addSubview:self.commentButton];
[cell addSubview:self.likeLabel];
[cell addSubview:self.heartIcon];
[cell addSubview:self.commentIcon];
[cell addSubview:self.commentText];
[cell addSubview:self.locationIcon];
[cell addSubview:self.heartButton];
return cell;
You're adding the labels to the view again every time the frame is loaded. the cellForRowAtIndexPath:
method is the wrong place to add custom fields to a cell.
You need to make a custom UITableViewCell
subclass and add the fields in there and expose them through either properties or methods and just set the new values in cellForRowAtIndexPath:
.
Hope that helps.
When you call dequeueReusableCellWithIdentifier
you may be given a cell that has already been displayed at another location in your table and then scrolled away. That's kind of what "reusable" means for cells.
You can either create a .xib file that contains your custom cell with all its views and just set data in your method or you can implement prepareForReuse
to remove the views you are adding.
You should really be subclassing UITableViewCell instead of creating views inside the cell itself.
However, if you really dont want to subclass (sublcassing is great). Create objects inside the cell creation method
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"InstaCell"];
UIButton *button = // etc...
}
Stop using self. objects inside cell too, if you are creating multiple copies, then dont make them global. Keep them local.
Using dequeueReusableCellWithIdentifier
the UITableViewDataSource protocol
will reuse cells, so you are adding views to cells that you already added views before.
Maybe not the best, but the simplest solution is to remove the subViews already added, before adding new ones.
before adding subviews try this:
for (UIView *subView in cell.contentView.subviews) {
[subView removeFromSuperview];
}
One more thing, you should be adding subview to cell.contentView
EDIT
Like Tim comment:
Adding and removing on every pass is wasteful, and could be risky if there are multiple places where views are inserted into rows.
EDIT
Your best solution is to create a custom UITableViewCell
YourCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"YourCellIdentifier"];
if (!cell) {
cell = [[YourCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"YourCellIdentifier"];
}
Then you could create a Xib and connect IBOutlet
.
Then, for example if you create an outlet for nameLabel
, you could do something like this:
[cell.nameLabel setText:entry[@"user"][@"full_name"]];
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.