防止重绘UICollectionView

时间:2014-02-15 14:36:53

标签: ios objective-c uicollectionview

我的目标是使用UICollectionView显示一行延迟加载的缩略图(数字未知),然后用户可以水平滚动缩略图。

我正在使用下面的代码来实现我的目标,但是我收到了错误。

前4个缩略图加载正常但滚动时缩略图开始以随机顺序绘制在彼此之上。

我试图让它达到以下目的:

Item 1 ----- Item 2 ----- Item 3 ---- Item 4

我希望这样的细胞只被绘制一次,类似于使用UITableView时的细胞。我只希望UICollectionView在我打电话时重新加载数据。

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

UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"cellIdentifier" forIndexPath:indexPath];

UIView *tmpView;

if([self.selectedEffects isEqualToString:@"Effects"]){

    int index = indexPath.row;

    NSLog(@"%i",index);

    tmpView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 70, 90)];
    [tmpView setBackgroundColor:[UIColor clearColor]];

    UIImageView *imageViewWithEffect = [[UIImageView alloc] initWithFrame:CGRectMake(5, 0, 60, 60)];
    imageViewWithEffect.layer.cornerRadius = 10.00;
    imageViewWithEffect.clipsToBounds = YES;

    UILabel *labelEffect = [[UILabel alloc] initWithFrame:CGRectMake(0, 65, 70, 20)];
    [labelEffect setText:[[self.activeEffectsArray objectAtIndex:index] objectAtIndex:1]];
    labelEffect.textAlignment = NSTextAlignmentCenter;
    labelEffect.textColor = [UIColor whiteColor];
    [labelEffect setFont:[UIFont boldSystemFontOfSize:8]];

    UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];

    [activityIndicator setFrame:CGRectMake(0, 0, 60, 60)];
    activityIndicator.alpha = 1.0;
    [activityIndicator startAnimating];

    UIButton *buttonSelect = [UIButton buttonWithType:UIButtonTypeCustom];
    [buttonSelect setFrame:CGRectMake(0, 0, 60, 90)];
    [buttonSelect setTag:index];
    [buttonSelect addTarget:self action:@selector(applyEffects:) forControlEvents:UIControlEventTouchUpInside];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{

        UIImage *imageWithEffect = [self editImage:[[self.activeEffectsArray objectAtIndex:indexPath.row] objectAtIndex:0] ImageToEdit:self.thumbnailImage];

        dispatch_async(dispatch_get_main_queue(), ^{

            [imageViewWithEffect setImage:imageWithEffect];
            [activityIndicator removeFromSuperview];

        });

    });

    [tmpView addSubview:imageViewWithEffect];
    [tmpView addSubview:labelEffect];
    [tmpView addSubview:activityIndicator];
    [tmpView addSubview:buttonSelect];

}

[cell addSubview:tmpView];

return cell;
}

1 个答案:

答案 0 :(得分:2)

您每次都会向细胞添加子视图。这是不正确的,因为细胞可能已被重复使用。检查子视图是否已创建,如果已经存在则修改它们。您可以通过继承UICollectionViewCell或使用viewWithTag:(前者更可取)来完成此操作。这里有数以百计的例子,所以我不会在这里重复。

您还在调度块中引用相同的视图。这也是不正确的,因为在调用块时可能已经重用了该单元。相反,使用indexPath再次获取单元格,并以这种方式进行修改。

最后,您可能需要考虑在背景线程上舍入图像角而不是使用layer.cornerRadius - 这种方法会导致图像混合,当您在显示大量图像时会导致不连续的滚动动画一旦。