【问题标题】:How to Maintain Button State in UICollectionViewCell?如何维护 UICollectionViewCell 中的按钮状态?
【发布时间】:2014-05-06 19:18:21
【问题描述】:

我正在使用 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

点赞按钮有它的作用:

- (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");

}
}

【问题讨论】:

    标签: ios parse-platform uicollectionviewcell


    【解决方案1】:

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

    以下只是一个建议,这个问题有几种解决方法,主要看你开发的风格。

    示例 1:
    将状态字段添加到数据源中的任何对象(可能会使您的对象类混乱)

    示例 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
    }
    

    【讨论】:

    • 感谢您如此明确的回答!我想我快到了。由于我是开发新手,因此我不得不再次寻求您的帮助。你能帮我建字典吗?
    • 我不知道如何完成这项工作,您能帮忙吗?
    【解决方案2】:

    我假设 VestmentaDetailCell 是 UICollectionViewCell 的子类。

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

    在这个类中如果你重写了这个方法:

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

    这通常用于清理代码,根据苹果文档定义here,它指出:

    当一个视图被出列使用时,这个方法在 相应的 dequeue 方法将视图返回给您的代码。子类 可以覆盖此方法并使用它将属性重置为其 默认值,通常使视图准备好再次使用。你 不应使用此方法将任何新数据分配给视图。那是 您的数据源对象的责任。

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

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

    然后我认为您还需要为您的喜欢按钮提供一个委托方法,该方法由您的视图控制器实现。在这个委托方法中,您所做的就是为按照威廉提到的方法点击的任何单元格填充字典或数组。

    【讨论】:

      猜你喜欢
      • 2019-07-18
      • 1970-01-01
      • 1970-01-01
      • 2019-09-06
      • 2021-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多