Adding CAGradientLayer to UIImageView in UICollectionViewCell has strange behavior
I need to add CAGradientLayer
some custom background image UICollectionViewCells
. I am using a custom flow layout that displays cells like this.
I'm having problems with reusability when scrolling in collectionView
and the gradient layers added to images are resizing. As you can see in this image, the gradient resizes.
I also have problems with some cells, these cells add a gradient layer twice. Thus, the shadow effect I want to add is too dark.
I am using this code.
- (void)prepareForReuse {
[super prepareForReuse];
[self.gradientLayer removeFromSuperlayer];
self.gradientLayer = nil;
self.articleImageView.image = nil;
}
- (void)layoutSubviews {
[super layoutSubviews];
[self setupGradient];
}
#pragma mark - Setup
- (void)setupGradient {
UIColor *threeQuartersBlack = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.6];
UIColor *halfBlack = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
UIColor *oneQuarterBlack = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.3];
CAGradientLayer *gradient = [CAGradientLayer layer];
CGFloat gradientHeight =self.bounds.size.height/3.0;
CGRect gradientBounds = CGRectMake(0, self.bounds.size.height-gradientHeight, self.bounds.size.width, gradientHeight);
gradient.frame = gradientBounds;
gradient.anchorPoint = CGPointMake(0.5, 0.5);
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor clearColor] CGColor],(id)oneQuarterBlack.CGColor ,(id)halfBlack.CGColor , (id)threeQueartesBlack.CGColor, (id)[[UIColor blackColor] CGColor], nil];
self.gradientLayer = gradient;
[self.articleImageView.layer insertSublayer:self.gradientLayer atIndex:0];
}
I noticed that if I pulled out this ViewController and rendered it again everything is correct.
Does anyone know what should I do to fix this problem?
thank
source to share
Potential solution: Remove the gradient from your UICollectionViewCell and instead add it to the displayed UIImage by creating a new UIImage that includes the gradient. The code for adding a gradient in UIImage is below.
UIImage *thumbnail = yourImage;
UIGraphicsBeginImageContextWithOptions(thumbnail.size, NO, 0.0);
[thumbnail drawInRect:CGRectMake(0.f, 0.f, thumbnail.size.width, thumbnail.size.height)];
// Add Gradient to lower half of thumbnail
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat colors[4] = {0.f, 0.f, 0.f, 0.55};
CGFloat locations[2] = {0.f, 1.f};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, 2);
CGColorSpaceRelease(colorSpace);
CGPoint startPoint = CGPointMake(thumbnail.size.width/2.f, thumbnail.size.height - 40.f);
CGPoint endPoint = CGPointMake(thumbnail.size.width/2.f, thumbnail.size.height);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
UIImage *newThumbnail = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
* Note: This code applies a thumbnail to the bottom 40 points of the photo. You can apply 25% of the photo to the bottom. If you use a photo in different sized view cells, the gradient will of course scale with the photo. If you want different ratios of gradient height: photo height, you will have to create multiple images. The best solution is probably to create all the different sizes of photos needed to view, loaded into a background thread and connected to the collection view cells as needed. This will ensure that image processing does not occur every time the view cell is reused. p>
source to share