Add blur in UICollectionViewCell

孤街浪徒 提交于 2019-12-24 13:02:07

问题


I'm trying get a snapshot of a UICollectionViewCell, blur it and add as a subview to the UICollectionViewCell.

Some weird problems are happening.

MyCollectionViewController

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell<MyCollectionViewCellProtocol> *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MyCollectionViewCell" forIndexPath:indexPath];
    cell.modelVariable = self.modelsArray[indexPath.item];
    return cell;
}



@interface MyCollectionViewCell : UICollectionViewCell <MyCollectionViewCellProtocol>

@property (strong, nonatomic) Promo *modelVariable;

@end


#import "UIImage+ImageEffects.h" // from WWDC 2013
#import "UIView+Snapshot.h" // My category to create a snapshot from a UIView
@implementation PromoRowCollectionViewCell

- (void)setModelVariable:(ModelVariableClass *)modelVariable
{
    _modelVariable = modelVariable;

    // just settings other stuff that is importante to the cell view
    self.mainImageView.image = modelVariable.mainImage;
    self.titleLabel.text = modelVariable.title;
    self.shortDescriptionLabel.text = modelVariable.detailedDescription;

    // removing the snapshot before taking other snapshot
    // or in case the cell is reused and this modelVariable is not in BlurState
    [self.blurImageView removeFromSuperview];
    self.blurImageView = nil;
    [self.myView removeFromSuperview];
    self.myView = nil;

    if (modelVariable.state == BlurState) {
        // Attempt 1
//        UIGraphicsBeginImageContext(self.bounds.size);
//        [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
//        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
//        UIGraphicsEndImageContext();

        // Attempt 2
//        UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.opaque, 0.0);
//        [self.layer renderInContext:UIGraphicsGetCurrentContext()];
//        UIImage *imgage = UIGraphicsGetImageFromCurrentImageContext();
//        UIGraphicsEndImageContext();

        // This was just a test that showed weird behavior
//        UIView *snapshotView = [self snapshotViewAfterScreenUpdates:YES];
//        self.myView = snapshotView;
//        snapshotView.backgroundColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.2];
//        CGRect frame = snapshotView.frame;
//        frame.origin = CGPointMake(20, 20);
//        snapshotView.frame = frame;
//        [self addSubview:snapshotView];

        // Attempt 3 // With the red background and shifting the frame we can see just a red rectangle and not the snapshot
        UIView *snapshotView = [self snapshotViewAfterScreenUpdates:YES];
        snapshotView.backgroundColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.2]; // Just to see things better

//        self.blockedPromoImageView = [[UIImageView alloc] initWithImage:image]; // for attempts 1 and 2

        self.blurImageView = [[UIImageView alloc] initWithImage:snapshotView.snapshotImage.applyLightEffect];

//        self.blurImageView.frame = self.bounds;
        self.blockedPromoImageView.frame = CGRectMake(20, 20, self.bounds.size.width, self.bounds.size.height); // Also to see things better

//        self.blockedPromoImageView.backgroundColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:0.2]; // for attempts 1 and 2

        [self addSubview:self.blurImageView];
    }
}

@end


UIView+Snapshot

- (UIImage *)snapshotImage
{
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return resultingImage;
}

Attempt 1:

Attempt 2:

Test with weird behavior:

Attempt 3:

So as you can see, attempts 1, 2 and 3 it seems they didn't take any snapshot. I'd expect the red rectangle to have a snapshot of the view in the back.

As for the weird behavior test, I'd expect what can be seen in the image, except for the red rectangle most at front.

Does anyone knows whats going on? Or how to solve it?

Thank you.

Edit:

I just created a simple project with the minimum amount of code to reproduce the problem. https://www.dropbox.com/sh/j1mhxj367kzn81y/AADW8ds9NvLMyjUDbn08mOJXa?dl=0


回答1:


You don't need to use the afterScreenUpdates flag if you just want your image and text change to come through in the screenshot.

You can just edit the image and text, remove views and save the cell as an image in the standard way:

-(UIImage*) takeSnapshot {

    UIGraphicsBeginImageContext(self.frame.size);
    [self.layer renderInContext: UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

Then add the blur and add to your view.

if (modelVariable.state == BlurState) {
    UIImage *snapshot = [self takeSnapshot];
    UIImage *blurredImage = [snapshot applyLightEffect];

    self.blurredImageView = [[UIImageView alloc] initWithImage:blurredImage];
    [self.view addSubview:self.blurredImageView];
}


来源:https://stackoverflow.com/questions/25369789/add-blur-in-uicollectionviewcell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!