我有一个UITableViewCell,它显示来自包含Instagram图片的JSON数组的数据。然而,UITableViewCell在某种意义上是混乱的,即每个相应的Cell在其上面具有先前的Cell数据。它更多的是UI问题,而不是实际的Web API问题。这个问题可以最好地显示在图片中,所以我在下面提供了一个 这是我正在使用的代码:
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;
答案 0 :(得分:1)
每次加载帧时,您都会再次将标签添加到视图中。
cellForRowAtIndexPath:
方法是向单元格添加自定义字段的错误位置。
您需要创建自定义UITableViewCell
子类并在其中添加字段并通过属性或方法公开它们,并在cellForRowAtIndexPath:
中设置新值。
希望有所帮助。
答案 1 :(得分:1)
当您致电dequeueReusableCellWithIdentifier
时,您可能会获得一个已经显示在表格中其他位置的单元格,然后滚动离开。这就是“可重复使用”对细胞意味着什么。
您可以创建包含自定义单元格及其所有视图的.xib文件,只需在方法中设置数据,也可以实现prepareForReuse
删除要添加的视图。
答案 2 :(得分:1)
你应该真正继承UITableViewCell,而不是在单元格内部创建视图。
然而,如果你真的不想要子类(sublcassing很棒)。在单元格创建方法中创建对象
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"InstaCell"];
UIButton *button = // etc...
}
停止使用自我。对于单元格内的对象,如果要创建多个副本,则不要将它们设置为全局。让他们在当地。
答案 3 :(得分:0)
使用dequeueReusableCellWithIdentifier
UITableViewDataSource protocol
将重复使用单元格,因此您要将视图添加到之前已添加视图的单元格中。
也许不是最好的,但最简单的解决方案是在添加新的子视图之前删除它们。
在添加子视图之前尝试:
for (UIView *subView in cell.contentView.subviews) {
[subView removeFromSuperview];
}
还有一点,您应该将子视图添加到cell.contentView
修改强>
像Tim评论一样:
在每次传递中添加和删除都是浪费,如果有多个地方将视图插入行中,则可能存在风险。
修改强>
您最好的解决方案是创建自定义UITableViewCell
YourCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"YourCellIdentifier"];
if (!cell) {
cell = [[YourCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"YourCellIdentifier"];
}
然后你可以创建一个Xib并连接IBOutlet
。
然后,例如,如果您为nameLabel
创建一个插座,您可以执行以下操作:
[cell.nameLabel setText:entry[@"user"][@"full_name"]];