如何在UICollectionViewCell中维护按钮状态?

时间:2014-05-06 19:18:21

标签: ios parse-platform uicollectionviewcell

我正在使用UICollectionView,我为其单元格设置了一个类。 在单元格中,我有一个图像和一个Like按钮,当点击它时会改变状态(更改按钮图像)。注意:我的collectionView水平显示并覆盖整个屏幕。

我的问题:正在重复使用单元格,并且每两个单元格都会更改类似的按钮状态。如果我喜欢image1,那么image3,image5也会改变Like按钮。如果我喜欢image2,那么image4,image6等会改变它们的状态。

我知道这与重复使用细胞有关。我的问题是如何修复它,以便每个按钮都是唯一的,或者按钮的状态设置为在每个单元格中取消选中。 我发现了一个涉及UITableView的类似问题,但答案似乎对我没有帮助。希望我能在这里找到答案。

我的代码: 注意:这是一个DetailView,因此数据已作为PFObject传递(我正在使用Parse.com后端)

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {

return 1;

}

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {

return 10;

}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

static NSString *cellIdentifier = @"Cell";
VestimentaDetailCell *cell = (VestimentaDetailCell *) [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];

cell.imageFile.image = [UIImage imageNamed:@"LoadLook.png"];

PFFile *storeLooks = [self.vestimenta objectForKey:[NSString stringWithFormat:@"image_%ld", (long)indexPath.item]];

[storeLooks getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
    if (!error && data.length > 0) {

        cell.imageFile.image = [UIImage imageWithData:data];

    } else {

        NSLog(@"No image found");

    }

return cell;
}

VestimentaDetailCell.m

Like按钮有其动作:

- (IBAction)likeLook:(id)sender {

    if ([sender isSelected]) {
        [sender setImage:[UIImage imageNamed:@"Like.png"] forState:UIControlStateNormal];
        [sender setSelected:NO];


    } else {
        [sender setImage:[UIImage imageNamed:@"Liked.png"] forState:UIControlStateSelected];
        [sender setSelected:YES];

        UIImageView *like = [[UIImageView alloc] initWithFrame:CGRectMake(120, 220, 100, 100)];
        like.image = [UIImage imageNamed:@"Love.png"];
        [self addSubview:like];
        [UIView animateWithDuration:2 animations:^{like.alpha = 0.0;}];

        NSLog(@"Liked Image");

}
}

2 个答案:

答案 0 :(得分:1)

通过将按钮链接到数据源或将索引映射到选定状态(可能是NSMutableDictionary或NSMutatbleArray)的数据结构来跟踪按钮的状态。

以下只是一个建议,这个问题有一些方法,主要是基于你开发的风格。

示例1:
将状态字段添加到dataSource中的任何对象(可能使对象类杂乱)

示例2: 如果使用字典,则键是单元格索引,值可以为空。如果选择了按钮,则将其放在字典中,如果没有,则不要。这样,查找速度很快,您可以快速了解它是否被选中。

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

static NSString *cellIdentifier = @"Cell";
VestimentaDetailCell *cell = (VestimentaDetailCell *) [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];

cell.imageFile.image = [UIImage imageNamed:@"LoadLook.png"];

PFFile *storeLooks = [self.vestimenta objectForKey:[NSString stringWithFormat:@"image_%ld", (long)indexPath.item]];

//============================================ Modified
BOOL selected = [self isCellPathSelected:indexPath.row];
// if selected, show in the UI, otherwise revert to not selected
//============================================ Modified


[storeLooks getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
    if (!error && data.length > 0) {

        cell.imageFile.image = [UIImage imageWithData:data];

    } else {

        NSLog(@"No image found");

    }

return cell;
}

//============================================ Modified
- (BOOL) isCellPathSelected:(int)index{
   //look in the dictionary, if there, return yes, otherwise return no
}

答案 1 :(得分:1)

我假设VestimentaDetailCell是UICollectionViewCell的子类。

在.h文件中创建按钮的属性。

在此课程中,如果您覆盖此方法:

- (void)prepareForReuse
{
      [super prepareForReuse];
      [yourbuttonproperty setImage:[UIImage imageNamed:@"Like.png"]
                          forState:UIControlStateNormal];
      [yourbuttonproperty setSelected:NO];
}

这通常用于清理代码,并根据apple docs定义here,它声明:

  

当视图出列以供使用时,此方法在之前调用   相应的dequeue方法将视图返回给您的代码。子类   可以覆盖此方法并使用它来重置属性   默认值,通常使视图可以再次使用。您   不应使用此方法将任何新数据分配给视图。那是   数据源对象的责任。

也许我在函数中实现的内容可能不符合您的要求,但我认为这是您需要使用的内容。

这将重置按钮状态而不是按下按钮状态。所以这意味着你的所有按钮都处于正常状态。

然后我认为您还需要一个由您的视图控制器实现的类似按钮的委托方法。在这个委托方法中,您所做的只是按照William提到的方法为任何已经点击的单元格填充字典或数组。