UIButton在UITableViewCell内意外重叠和隐藏

时间:2015-06-04 08:51:48

标签: ios objective-c uitableview uibutton

我在自定义UIButton内以编程方式创建了UITableViewCell,单元格内UIButtons的编号是动态的,起初它看起来很完美,但是当我打开所有折叠的单元格时并滚动表格视图UIButton相互重叠,如果我滚动更多,屏幕外的UIButton隐藏,当你回到屏幕区域时,图像看起来像是什么。

我不在这里发布代码,因为它很大,我不知道我应该在这里包含哪一部分。如果被问到,我会在这里发布该特定代码。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    InterestTableViewCell *cell = (InterestTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    NSString *category= (NSString *)[self.itemsInTable objectAtIndex:indexPath.row];
    NSMutableArray *subcat =[[NSMutableArray alloc] init];
    NSArray *keys = [cat allKeys];
    id aKey = [keys objectAtIndex:indexPath.row];
    subcat = [cat objectForKey:aKey];
    cell.btnGroupTap.tag = indexPath.row+10000;
    NSArray *count=(NSArray *)subcat;
    int xoffset;
    int yoffset = 0;
    for(int i=0; i<count.count;i++)
    {
         if(i==0)
        {
            xoffset=0;
        }
        else
        {
            if(i%2 == 0)
            {
            xoffset = 0;
            }
            else
            {
                xoffset = 150;
            }
        }
        if(i==0)
        {
            yoffset = 0;
        }
        else
        {
            if(i%2==0)
            {
                yoffset = yoffset+45;
            }
        }
        NSString *sel = subcat[i][@"selected"];
        NSString *key =subcat[i][@"key"];
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        UIImage *image;
        if(![sel boolValue])
        {
            image = [UIImage imageNamed: @"unchecked.png"];
        }
        else
        {
            image = [UIImage imageNamed: @"checked.png"];
        }
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(29,18,20,20)];
        [imageView setImage:image];
        UILabel *lbl1 = [[UILabel alloc] init];
        [lbl1 setFrame:CGRectMake(0,5,100,20)];
        lbl1.backgroundColor=[UIColor clearColor];
        lbl1.textColor=[UIColor blackColor];
        lbl1.frame = CGRectMake(40,0,100,40);
        lbl1.numberOfLines =0;
        [lbl1 setFont:[UIFont fontWithName:@"Roboto-Light" size:12]];
        lbl1.text= subcat[i][@"value"];
        button.tag= [key integerValue];
        [button setTitle:@"" forState:UIControlStateNormal];
        button.imageView.contentMode = UIViewContentModeScaleAspectFit;
        [button setBackgroundImage:image forState:normal];
        CGRect screenRect = [[UIScreen mainScreen] bounds];
        CGFloat screenWidth = screenRect.size.width;
        button.frame = CGRectMake(xoffset,20+yoffset,(screenWidth/2)-40,40);
        [button addTarget:self action:@selector(CheckAction:) forControlEvents:UIControlEventTouchUpInside];
        [button addSubview:lbl1];
        [cell.ContainerView addSubview:button];
        [cell.ContainerView bringSubviewToFront:button];
    }
    cell.ContainerView.hidden=YES;
    cell.lblCategory.text = category;
    return cell;
}

Full Code at github

注意:我在[tableView beginUpdates];[tableView endUpdates];中使用了didSelectRowAtIndexPath

2 个答案:

答案 0 :(得分:2)

问题是您正在使用可重复使用的单元格。可以把它想象成市场上的购物车。你永远不会知道它是否是新的,也许你会得到一个已经在其中的产品。您应该始终在cellForRowAtIndexPath中清理您的单元格,然后继续执行您的代码。

<强> #edit 好像清理容器View应该有所帮助。像:

InterestTableViewCell *cell = (InterestTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
[[cell.ContainerView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];

答案 1 :(得分:0)

当您通过reusable cells使用dequeueReusableCellWithIdentifier时:因此,如果重复使用该单元格,那么它将具有之前添加的CategoryView(基本上为subviews)。你需要先删除它们而不是新的它们,你需要将其作为

for (UIView *subview in cell.ContainerView.subViews) {
    if ([subview isKindOfClass:[UIButton class]]) {
        [((UIButton *) subview) removeTarget:nil
                       action:NULL
             forControlEvents:UIControlEventAllEvents];  
        [subview removeFromSuperview];
    }
}

cellForRowAtIndexPath:method as -

中添加上述方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    InterestTableViewCell *cell = (InterestTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    for (UIView *subview in cell.ContainerView.subViews) {
     if ([subview isKindOfClass:[UIButton class]]) {
          [((UIButton *) subview) removeTarget:nil
                                        action:NULL
           forControlEvents:UIControlEventAllEvents];  
          [subview removeFromSuperview];
        }
    }

    NSString *category= (NSString *)[self.itemsInTable objectAtIndex:indexPath.row];
        NSMutableArray *subcat =[[NSMutableArray alloc] init];
        NSArray *keys = [cat allKeys];
        id aKey = [keys objectAtIndex:indexPath.row];
        subcat = [cat objectForKey:aKey];
        cell.btnGroupTap.tag = indexPath.row+10000;
        NSArray *count=(NSArray *)subcat;
        int xoffset;
        int yoffset = 0;
        for(int i=0; i<count.count;i++)
        {
             if(i==0)
            {
                xoffset=0;
            }
            else
            {
                if(i%2 == 0)
                {
                xoffset = 0;
                }
                else
                {
                    xoffset = 150;
                }
            }
            if(i==0)
            {
                yoffset = 0;
            }
            else
            {
                if(i%2==0)
                {
                    yoffset = yoffset+45;
                }
            }
            NSString *sel = subcat[i][@"selected"];
            NSString *key =subcat[i][@"key"];
            UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
            UIImage *image;
            if(![sel boolValue])
            {
                image = [UIImage imageNamed: @"unchecked.png"];
            }
            else
            {
                image = [UIImage imageNamed: @"checked.png"];
            }
            UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(29,18,20,20)];
            [imageView setImage:image];
            UILabel *lbl1 = [[UILabel alloc] init];
            [lbl1 setFrame:CGRectMake(0,5,100,20)];
            lbl1.backgroundColor=[UIColor clearColor];
            lbl1.textColor=[UIColor blackColor];
            lbl1.frame = CGRectMake(40,0,100,40);
            lbl1.numberOfLines =0;
            [lbl1 setFont:[UIFont fontWithName:@"Roboto-Light" size:12]];
            lbl1.text= subcat[i][@"value"];
            button.tag= [key integerValue];
            [button setTitle:@"" forState:UIControlStateNormal];
            button.imageView.contentMode = UIViewContentModeScaleAspectFit;
            [button setBackgroundImage:image forState:normal];
            CGRect screenRect = [[UIScreen mainScreen] bounds];
            CGFloat screenWidth = screenRect.size.width;
            button.frame = CGRectMake(xoffset,20+yoffset,(screenWidth/2)-40,40);
            [button addTarget:self action:@selector(CheckAction:) forControlEvents:UIControlEventTouchUpInside];
            [button addSubview:lbl1];
            [cell.ContainerView addSubview:button];
            [cell.ContainerView bringSubviewToFront:button];
        }
    cell.ContainerView.hidden=YES;
    cell.lblCategory.text = category;
    return cell;
}

注意:此外,如果您使用手动内存管理方案进行内存管理,则需要正确平衡对象的保留计数,例如在创建任何subview并添加后在那里发出release消息。如果不再需要,最后将其从superview中删除。我已在您的removeFromSuperView:方法中添加了这些release / cellForRowAtIndexPath条款。

但是,当您使用ARC时,系统将管理对象的保留/释放调用以管理内存