UICollectionView部分重叠

时间:2014-12-14 03:44:21

标签: ios objective-c cocoa-touch uicollectionview uicollectionviewlayout

我遇到了一个问题,即我的收藏视图中的对象会无意间碰撞并互相交互。

说明:

我有一个UICollectionView,我用自定义的UICollectionViewCell对象填充。这一切都很好,很好。我还有标题来分隔每个部分。

现在,这些按钮的基本功能之一是关闭状态和开启状态。

但问题是,当我按下按钮时," on"对于我的第一部分中的某些内容,它会变成" on"或者"关闭"我的上一部分中的一个按钮,显示在屏幕外。此外,章节标题也有重叠。 enter image description here

以下是生成每个单元格的代码:

自定义单元格类

- (id) initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.tagBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        self.tagBtn.frame = CGRectMake(-frame.size.width/4+20, -frame.size.width/4+15, frame.size.width, frame.size.height);
        [[self.tagBtn layer] setBorderColor:[[UIColor colorWithRed:234.0f/255.0f green:99.0f/255.0f blue:74.0f/255.0f alpha:1.0f] CGColor]];
        [[self.tagBtn layer] setBorderWidth:1.0f];
        self.tagBtn.backgroundColor = [UIColor whiteColor];
        [self.tagBtn setTitleColor:[UIColor colorWithRed:234.0f/255.0f green:99.0f/255.0f blue:74.0f/255.0f alpha:1.0f] forState:UIControlStateNormal];
        self.tagBtn.titleLabel.font = [UIFont systemFontOfSize:12.0f];
        [self.tagBtn addTarget:self action:@selector(toggleTag) forControlEvents:UIControlEventTouchUpInside];
        [self.contentView addSubview:self.tagBtn];

    }

    return self;
}

单元格数据源代理

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    TagCellCollectionViewCell *cell = (TagCellCollectionViewCell *) [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
    NSArray *data = [dataArray objectAtIndex:indexPath.section];
    // Configure the cell

    NSString *labelText = data[indexPath.row];

    [cell.tagBtn setTitle:labelText forState:UIControlStateNormal];

    return cell;
}

按钮切换方法

- (void) toggleTag {
    if (self.tagBtn.backgroundColor == [UIColor whiteColor]) {
        self.tagBtn.backgroundColor = [UIColor colorWithRed:234.0f/255.0f green:99.0f/255.0f blue:74.0f/255.0f alpha:1.0f];
        [self.tagBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    }
    else {
        self.tagBtn.backgroundColor = [UIColor whiteColor];
        [self.tagBtn setTitleColor:[UIColor colorWithRed:234.0f/255.0f green:99.0f/255.0f blue:74.0f/255.0f alpha:1.0f] forState:UIControlStateNormal];
    }
}

章节标题

- (UICollectionReusableView *) collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
    if (kind == UICollectionElementKindSectionHeader) {
        UICollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"Header" forIndexPath:indexPath];
        if (headerView == nil) {
            headerView = [[UICollectionReusableView alloc] initWithFrame:CGRectMake(5, 0, 320, 25)];
        }

        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(15, 0, 320, 25)];
        label.text = [NSString stringWithFormat:@"Section %li", indexPath.section];
        [label setTextColor:[UIColor colorWithRed:38.0f/255.0f green:34.0f/255.0f blue:108.0f/255.0f alpha:1.0f]];
        headerView.backgroundColor = [UIColor colorWithRed:204.0f/255.0f green:204.0f/255.0f blue:222.0f/255.0f alpha:1.0f];
        [headerView addSubview:label];
        return headerView;
    }
    return nil;
}

您还有什么想看的吗?

更新

新按钮代码,答案如下

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    TagCellCollectionViewCell *cell = (TagCellCollectionViewCell *) [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
    NSArray *data = [dataArray objectAtIndex:indexPath.section];
    // Configure the cell

    NSString *labelText = data[indexPath.row];

    [cell.tagBtn setTitle:labelText forState:UIControlStateNormal];
    [cell.tagBtn addTarget:self action:@selector(toggleTag:) forControlEvents:UIControlEventTouchUpInside];
    cell.tagBtn.tag = indexPath.row + 1000*indexPath.section;


    if (self.toggledIndexPath == indexPath) {
        cell.tagBtn.backgroundColor = [UIColor colorWithRed:234.0f/255.0f green:99.0f/255.0f blue:74.0f/255.0f alpha:1.0f];
        [cell.tagBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    }
    else {
        cell.tagBtn.backgroundColor = [UIColor whiteColor];
        [cell.tagBtn setTitleColor:[UIColor colorWithRed:234.0f/255.0f green:99.0f/255.0f blue:74.0f/255.0f alpha:1.0f] forState:UIControlStateNormal];

    }
    return cell;
}

- (void) toggleTag:(UIButton *) btn {
    NSIndexPath *path;
    if (btn.backgroundColor == [UIColor whiteColor]) {
        path = [NSIndexPath indexPathForItem:btn.tag/1000 inSection:btn.tag % 1000];
    }else{
        path = [NSIndexPath indexPathForItem:-1 inSection:0];
    }
    self.toggledIndexPath = path;
    [self.collectionView reloadData];
}

2 个答案:

答案 0 :(得分:2)

您的代码有几个与单元格和标题视图重用有关的问题。您对单元格UI所做的任何更改都应该在cellForItemAtIndexPath中完成,而不是像在按钮的操作方法中那样。如果在action方法中执行此操作,则在重用该单元格时,该按钮仍将具有这些更改的值,但现在位于集合视图中的不同位置。您需要获取触摸按钮的单元格的indexPath。有几种方法可以做到这一点,最简单的方法是给你的按钮一个基于indexPath的标签(当你有部分时,你需要使用两者,比如button.tag = indexPath.row + 1000 * indexPath.section )。在按钮的操作方法中,您应该在数据源中设置一些属性,指示特定indexPath上的按钮应该更改其属性,然后在cellForItemAtIndexPath中的if-else子句中更改它们。

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    TagCellCollectionViewCell *cell = (TagCellCollectionViewCell *) [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
    NSArray *data = [dataArray objectAtIndex:indexPath.section];
    NSString *labelText = data[indexPath.row];
    [cell.tagBtn setTitle:labelText forState:UIControlStateNormal];
    [cell.tagBtn addTarget:self action:@selector(toggleTag:) forControlEvents:UIControlEventTouchUpInside];
    cell.tagBtn.tag = indexPath.row + 1000*indexPath.section;
    if (self.toggledIndexPath == indexPath) {
        cell.tagBtn.backgroundColor = [UIColor colorWithRed:234.0f/255.0f green:99.0f/255.0f blue:74.0f/255.0f alpha:1.0f];
        [self.tagBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    }else {
        cell.tagBtn.backgroundColor = [UIColor whiteColor];
        [cell.tagBtn setTitleColor:[UIColor colorWithRed:234.0f/255.0f green:99.0f/255.0f blue:74.0f/255.0f alpha:1.0f] forState:UIControlStateNormal];
    }
    return cell;
}

- (void) toggleTag:(UIButton *) btn {
    if (self.tagBtn.backgroundColor == [UIColor whiteColor]) {
        indexPath *path = [NSIndexPath indexPathForItem:btn.tag % 1000 inSection:btn.tag/1000];
    }else{
        indexPath *path = [NSIndexPath indexPathForItem:-1 inSection:0];
    }
    self.toggledIndexPath = path;
    [self.tableView reloadData];
}

请注意,我在cellForRowAtIndexPath中添加了按钮的操作方法,而不是在按钮的init方法中。 toggledIndexPath是我添加的属性,用于跟踪触摸的按钮。

部分标题的问题在于,您要向headerView添加多个标签,因为当调用viewForSupplementaryElementOfKind并且它有一个要重复使用的单元格时,您仍然会向其添加标签。您应该在xib中创建视图,或者在视图的init方法中添加任何子视图(如果您在代码中执行所有操作)。您应该在viewForSupplementaryElementOfKind中做的唯一事情是设置标题并返回视图。

答案 1 :(得分:1)

集合视图部分重叠问题解决此代码

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {


        UICollectionReusableView *reusableview=nil;
        reusableview = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath];

        NSArray *viewsToRemove = [reusableview subviews];
        for (UIView *v in viewsToRemove) {
            [v removeFromSuperview];
        }
        if (reusableview==nil) {
            reusableview=[[UICollectionReusableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 30)];
        }
        reusableview.backgroundColor=[UIColor colorWithRed:234.0/255.0 green:234.0/255.0 blue:234.0/255.0 alpha:1.0];

        UILabel *lblTitle=[[UILabel alloc] initWithFrame:CGRectMake(10, 0, [UIScreen mainScreen].bounds.size.width-90, 30)];
        [lblTitle setFont:[UIFont fontWithName:@"Ubuntu-Light" size:12]];

        lblTitle.textColor=HTAtHomeColor;
        [reusableview addSubview:lblTitle];

        UILabel *lblCount=[[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width-80, 0, 70, 30)];
        lblCount.textAlignment=NSTextAlignmentRight;
        lblCount.textColor=[UIColor blackColor];
        [lblCount setFont:[UIFont fontWithName:@"Ubuntu-Light" size:12]];

        if (indexPath.section==0){
            lblCount.text=[NSString stringWithFormat:@"%ld Selected",(long)mealTypeCount];
            lblTitle.text=[NSString stringWithFormat:@"MEAL TYPE"];
        }
        else if (indexPath.section==1){
            lblCount.text=[NSString stringWithFormat:@"%ld Selected",(long)mealOfDayCount];
            lblTitle.text=[NSString stringWithFormat:@"MEAL OF THE DAY"];
        }
        else if (indexPath.section==2){
            lblCount.text=[NSString stringWithFormat:@"%ld Selected",(long)cuisineCount];
            lblTitle.text=[NSString stringWithFormat:@"TYPES OF CUSINE"];
        }

        [reusableview addSubview:lblCount];

        return reusableview;
    }
    return nil;
}