UILabel在UITableViewCell

时间:2015-04-26 22:00:33

标签: ios objective-c uitableview uilabel

我有一个UITableViewCell,它显示来自包含Instagram图片的JSON数组的数据。然而,UITableViewCell在某种意义上是混乱的,即每个相应的Cell在其上面具有先前的Cell数据。它更多的是UI问题,而不是实际的Web API问题。这个问题可以最好地显示在图片中,所以我在enter image description here下面提供了一个 这是我正在使用的代码:

   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;

4 个答案:

答案 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"]];