IOS: round the cournes of a uicollectionViewCell clipin it's contents - ios

I have a collection view with multiple cell styles and sizes I want to round the corners of the cell using this helper function:
void roundCornersOfAView(UIView *view, CGFloat radius, BOOL shadow){
CALayer* layer = [view layer];
[layer setCornerRadius:radius];
[layer setBorderColor:[UIColor blackColor].CGColor];
[layer setMasksToBounds:YES];
// CALayer* mask = [CALayer layer];
// [mask setFrame:CGRectMake(layer.frame.origin.x, layer.frame.origin.y, layer.frame.size.width, layer.frame.size.height)];
// [mask setCornerRadius:radius];
// [layer setMask:mask];
if (shadow) {
[layer setBorderWidth:0.5f];
//[layer setMasksToBounds:NO];
[layer setShadowColor:[UIColor blackColor].CGColor];
[layer setShadowOpacity:1.0];
[layer setShadowRadius:1.0];
[layer setShadowOffset:CGSizeMake(0.0, 0.0)];
}
[layer setMasksToBounds:YES];
}
using it like this in my cell for row at index path:
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:... forIndexPath:indexPath];
roundCornersOfAView([cell contentView], 30, YES);
The problem is that images on cell are not clipped in the rounded courners, neither labels or any other subviews, it only clips the background color... what is the best way to round courners and clip its content just like the instagram app?

Calling it like this:
roundCornersOfAView(cell, 30, YES);
using the helper function like this:
void roundCornersOfAView(UIView *view, CGFloat radius, BOOL shadow){
CALayer* layer = [view layer];
[layer setCornerRadius:radius];
[layer setBorderWidth:0.0f];
if (shadow) {
[layer setBorderColor:[UIColor blackColor].CGColor];
[layer setBorderWidth:0.1f];
[layer setShadowColor:[UIColor blackColor].CGColor];
[layer setShadowOpacity:0.5];
[layer setShadowRadius:1.5];
[layer setShadowOffset:CGSizeMake(0.0, 1.0)];
}
[layer setMasksToBounds:YES];
}
The problem was that I was sending the content view instead of the cell itself.

Related

Add Rounded corners after resizing UIImageView

Facing problem when adding rounded corners to imageview.
here is my code
CALayer * lay = [imageview layer];
[lay setMasksToBounds:YES];
[lay setCornerRadius:10.0];
[lay setBorderWidth:5.0];
[lay setBorderColor:[[UIColor clearColor] CGColor]];
imageview.layer.rasterizationScale = [UIScreen mainScreen].scale;
imageview.layer.shouldRasterize = YES;
And its working fine but if I am resizing the imageview, its not making corners round.
Here is my resizing code:
[UIView animateWithDuration:0.2 animations:^ {
[imageview setTransform:CGAffineTransformMakeScale(1.1, 1.1)];
CALayer * l = [imageview layer];
[l setMasksToBounds:YES];
[l setCornerRadius:10.0];
[l setBorderWidth:5.0];
[l setBorderColor:[[UIColor clearColor] CGColor]];
imageview.layer.rasterizationScale = [UIScreen mainScreen].scale;
imageview.layer.shouldRasterize = YES;
newimage = imageview.image;
[[NSUserDefaults standardUserDefaults] setValue:UIImageJPEGRepresentation(newimage,1.1) forKey:#"newimage"];
}];
Any help would be appreciated.
You can set corner radius from storyboard or XIB hope it will work, Please check This.
Plz import the QuartzCore/QuartzCore.h
and then write the code ...
yourImageView.layer.cornerRadius = yourRadius;
yourImageView.clipsToBounds = YES;
Why to write the clipsToBounds property
A Boolean value that determines whether subviews are confined to the bounds of the view.
Discussion
Setting this value to YES causes subviews to be clipped to the bounds of the receiver. If set to NO, subviews whose frames extend beyond the visible bounds of the receiver are not clipped. The default value is NO.
Try
[UIView animateWithDuration:0.2
delay:0.1
options: UIViewAnimationOptionCurveEaseOut
animations:^
{
[imageview setTransform:CGAffineTransformMakeScale(1.1, 1.1)];
}
completion:^(BOOL finished)
{
[imageview.layer setCornerRadius:10.0];
imageview.clipsToBounds = YES;
imageview.layer.masksToBounds = YES;
[imageview.layer setBorderWidth:5.0];
[imageview.layer setBorderColor:[[UIColor clearColor] CGColor]];
newimage = imageview.image;
[[NSUserDefaults standardUserDefaults] setValue:UIImageJPEGRepresentation(newimage,1.1) forKey:#"newimage"];
}];
You have to round corners after animation complete. You may get animation completion as above.

How will the UIGestureRecognizer identify which circle was tapped?

I am trying to tap one of five circles and start an animation that will gradually change the selected background to the same colour as the tapped circle. I’ve managed to get UITapGestureRecognizer to respond to a tap gesture on any one of five circles but I can’t work out how to find out how to identify each circle.
The UIKit Framework Reference documentation on UIGestureRecognizer says
A gesture recognizer operates on touches hit-tested to a specific view
and all of that view’s subviews
and that
Clients of gesture recognisers can also ask for the location of a
gesture by calling locationInView: or locationOfTouch:inView”.
This made me think the tapped circles probably need to be made into images.
But is this really what I need to do ?
Here’s the code so far
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithRed:240/255.0 green:240/255.0 blue:240/255.0 alpha:1.0];
[self.view setUserInteractionEnabled:YES];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(method:)];
tap.numberOfTapsRequired = 1;
[self.view addGestureRecognizer:tap];
CAShapeLayer *circleLayer1 = [CAShapeLayer layer];
[circleLayer1 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(75.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer1 setStrokeColor:[[UIColor cyanColor] CGColor]];
[circleLayer1 setFillColor:[[UIColor cyanColor] CGColor]];
[[self.view layer] addSublayer:circleLayer1];
CAShapeLayer *circleLayer2 = [CAShapeLayer layer];
[circleLayer2 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(125.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer2 setStrokeColor:[[UIColor redColor] CGColor]];
[circleLayer2 setFillColor:[[UIColor redColor] CGColor]];
[[self.view layer] addSublayer:circleLayer2];
CAShapeLayer *circleLayer3 = [CAShapeLayer layer];
[circleLayer3 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(175.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer3 setStrokeColor:[[UIColor yellowColor] CGColor]];
[circleLayer3 setFillColor:[[UIColor yellowColor] CGColor]];
[[self.view layer] addSublayer:circleLayer3];
CAShapeLayer *circleLayer4 = [CAShapeLayer layer];
[circleLayer4 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(225.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer4 setStrokeColor:[[UIColor magentaColor] CGColor]];
[circleLayer4 setFillColor:[[UIColor magentaColor] CGColor]];
[[self.view layer] addSublayer:circleLayer4];
CAShapeLayer *circleLayer5 = [CAShapeLayer layer];
[circleLayer5 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(275.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer5 setStrokeColor:[[UIColor greenColor] CGColor]];
[circleLayer5 setFillColor:[[UIColor greenColor] CGColor]];
[[self.view layer] addSublayer:circleLayer5];
}
- (void)method:(id)sender {
[UIView animateWithDuration:3.0 animations:^{
self.view.layer.backgroundColor = [UIColor cyanColor].CGColor;
} completion:NULL];
}
To show what I’m trying to do, I’ve set up the method so it changes the background layer to the colour of the circle on the left.
But what do I need to do [a] to identify which circle was tapped and [b] represent the tapped spots as circles that would also gradually change colour so the whole screen changes to the colour of the circle that was tapped ?
I suggest you to remove the UITapGestureRecognizer that you added to the whole view.
Then add a name to each CAShapeLayer so you can distinguish between them :
self.view.backgroundColor = [UIColor colorWithRed:240/255.0 green:240/255.0 blue:240/255.0 alpha:1.0];
[self.view setUserInteractionEnabled:YES];
CAShapeLayer *circleLayer1 = [CAShapeLayer layer];
[circleLayer1 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(75.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer1 setStrokeColor:[[UIColor cyanColor] CGColor]];
[circleLayer1 setFillColor:[[UIColor cyanColor] CGColor]];
[circleLayer1 setName:#"circleLayer1"];
[[self.view layer] addSublayer:circleLayer1];
CAShapeLayer *circleLayer2 = [CAShapeLayer layer];
[circleLayer2 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(125.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer2 setStrokeColor:[[UIColor redColor] CGColor]];
[circleLayer2 setFillColor:[[UIColor redColor] CGColor]];
[circleLayer2 setName:#"circleLayer2"];
[[self.view layer] addSublayer:circleLayer2];
CAShapeLayer *circleLayer3 = [CAShapeLayer layer];
[circleLayer3 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(175.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer3 setStrokeColor:[[UIColor yellowColor] CGColor]];
[circleLayer3 setFillColor:[[UIColor yellowColor] CGColor]];
[circleLayer3 setName:#"circleLayer3"];
[[self.view layer] addSublayer:circleLayer3];
CAShapeLayer *circleLayer4 = [CAShapeLayer layer];
[circleLayer4 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(225.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer4 setStrokeColor:[[UIColor magentaColor] CGColor]];
[circleLayer4 setFillColor:[[UIColor magentaColor] CGColor]];
[circleLayer4 setName:#"circleLayer4"];
[[self.view layer] addSublayer:circleLayer4];
CAShapeLayer *circleLayer5 = [CAShapeLayer layer];
[circleLayer5 setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(275.0, 260.0, 50.0, 50.0)] CGPath]];
[circleLayer5 setStrokeColor:[[UIColor greenColor] CGColor]];
[circleLayer5 setFillColor:[[UIColor greenColor] CGColor]];
[circleLayer5 setName:#"circleLayer5"];
[[self.view layer] addSublayer:circleLayer5];
Then you can add this method that allows you to detect wich CAShapeLayer has been touched:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches) {
CGPoint touchLocation = [touch locationInView:self.view];
for (id sublayer in self.view.layer.sublayers) {
if ([sublayer isKindOfClass:[CAShapeLayer class]]) {
CAShapeLayer *shapeLayer = sublayer;
if (CGPathContainsPoint(shapeLayer.path, 0, touchLocation, YES)) {
NSLog(#"Layer's name is: %#",shapeLayer.name);
}
}
}
}
}
Now that you can detect which CAShapeLayer has been touched, you can customize the color of your view as you prefer
There is a method called locationInView:(UIView *)view that will help you to find the location. You know the rects of all the circles and check whether the location is inside of any rect using the method CGRectContainsPoint(CGRect rect, CGPoint point) If its inside you can check whether the selected location is radius distance from the centre. Hope this will solve your issue.
For Q.(b) I attached a sample you can refer it,
UIColor *stroke = rippleColor ? rippleColor : [UIColor colorWithWhite:0.8 alpha:0.8];
CGRect pathFrame = CGRectMake(-CGRectGetMidX(self.bounds), -CGRectGetMidY(self.bounds), self.bounds.size.width, self.bounds.size.height);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:pathFrame cornerRadius:self.layer.cornerRadius];
// accounts for left/right offset and contentOffset of scroll view
CGPoint shapePosition = [self convertPoint:self.center fromView:nil];
CAShapeLayer *circleShape = [CAShapeLayer layer];
circleShape.path = path.CGPath;
circleShape.position = shapePosition;
circleShape.fillColor = [UIColor clearColor].CGColor;
circleShape.opacity = 0;
circleShape.strokeColor = stroke.CGColor;
circleShape.lineWidth = 3;
[self.layer addSublayer:circleShape];
[CATransaction begin];
//remove layer after animation completed
[CATransaction setCompletionBlock:^{
[circleShape removeFromSuperlayer];
}];
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:#"transform.scale"];
scaleAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
scaleAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(2.5, 2.5, 1)];
CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:#"opacity"];
alphaAnimation.fromValue = #1;
alphaAnimation.toValue = #0;
CAAnimationGroup *animation = [CAAnimationGroup animation];
animation.animations = #[scaleAnimation, alphaAnimation];
animation.duration = 0.5f;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
[circleShape addAnimation:animation forKey:nil];
[CATransaction commit];
}
[UIView animateWithDuration:0.1 animations:^{
imageView.alpha = 0.4;
self.layer.borderColor = [UIColor colorWithWhite:1 alpha:0.9].CGColor;
}completion:^(BOOL finished) {
[UIView animateWithDuration:0.2 animations:^{
imageView.alpha = 1;
self.layer.borderColor = [UIColor colorWithWhite:0.8 alpha:0.9].CGColor;
}completion:^(BOOL finished) {
if([superSender respondsToSelector:methodName]){
[superSender performSelectorOnMainThread:methodName withObject:nil waitUntilDone:NO];
}
if(_block) {
BOOL success= YES;
_block(success);
}
}];
}];
}`
As pointed by the others answers you have some options, but I think that the easiest, is to check in your method what layer you tapped.
You just need to change your method to something like that:
- (void)method:(UITapGestureRecognizer *)gesture {
CGPoint touchLocation = [gesture locationInView:self.view];
for (id sublayer in self.view.layer.sublayers) {
if ([sublayer isKindOfClass:[CAShapeLayer class]]) {
CAShapeLayer *shapeLayer = sublayer;
if (CGPathContainsPoint(shapeLayer.path, 0, touchLocation, YES)) {
[UIView animateWithDuration:3.0 animations:^{
shapeLayer.strokeColor = [UIColor blackColor].CGColor;
shapeLayer.fillColor = [UIColor blackColor].CGColor;
} completion:NULL];
}
}
}
}
You don't need to add any UITapGestureRecognizer to your view, you just need to add names to your layers and implement the following method:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
for (UITouch *touch in touches) {
CGPoint touchLocation = [touch locationInView:self.view];
for (id sublayer in self.view.layer.sublayers) {
if ([sublayer isKindOfClass:[CAShapeLayer class]]) {
CAShapeLayer *shapeLayer = sublayer;
if (CGPathContainsPoint(shapeLayer.path, 0, touchLocation, YES)) {
// This touch is in this shape layer
NSLog(#"Name of layer is: %#",shapeLayer.name);
}
} else {
CALayer *layer = sublayer;
if (CGRectContainsPoint(layer.frame, touchLocation)) {
// Touch is in this rectangular layer
}
}
}
}
}
After identifing your layer you can change the color of layer accordingly.
Or if you have limited layers than you can identify it as follows for your no of layers:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
for (UITouch *touch in touches) {
CGPoint touchLocation = [touch locationInView:self.view];
if (CGPathContainsPoint(shape1.path, 0, touchLocation, YES)) {
// This touch is in this shape layer
NSLog(#"Name of layer 1 is: %#",shape1.name);
}
if (CGPathContainsPoint(shape2.path, 0, touchLocation, YES)) {
// This touch is in this shape layer
NSLog(#"Name of layer 2 is: %#",shape2.name);
}
if (CGPathContainsPoint(shape3.path, 0, touchLocation, YES)) {
// This touch is in this shape layer
NSLog(#"Name of layer 3 is: %#",shape3.name);
}
if (CGPathContainsPoint(shape4.path, 0, touchLocation, YES)) {
// This touch is in this shape layer
NSLog(#"Name of layer 4 is: %#",shape4.name);
}
if (CGPathContainsPoint(shape5.path, 0, touchLocation, YES)) {
// This touch is in this shape layer
NSLog(#"Name of layer 5 is: %#",shape5.name);
}
}
}

Draw a gesture control resizable circle in iOS

I want to draw a circle in iOS. It can be an image view or view, I want to adjust its size on gestures. Like, dragging from outside to the center, the radius of the circle should reduce and so vice versa.
Please note that I want to fix the position of that view, circle or image. I just want to adjust the size as it is dragged.
try this
- (IBAction)pinch:(UIPinchGestureRecognizer *)sender {
double scale=[sender scale];
self.view1.frame=CGRectMake(self.view1.frame.origin.x*scale, self.view1.frame.origin.y*scale, self.view1.frame.size.width*scale, self.view1.frame.size.height*scale);
[self.view1.layer setCornerRadius:5];
}
Try this.
- (IBAction)pan:(UIPanGestureRecognizer *)sender {
for (CALayer *layer in self.imageView.layer.sublayers) {
[layer removeFromSuperlayer];
}
CGPoint scale =[sender locationInView:sender.view];
CAShapeLayer *circleLayer = [CAShapeLayer layer];
[circleLayer setBounds:CGRectMake(0.0f, 0.0f, [_imageView bounds].size.width,
[_imageView bounds].size.height)];
[circleLayer setPosition:CGPointMake(CGRectGetMidX([_imageView bounds]),CGRectGetMidY([_imageView bounds]))];
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, CGRectGetWidth(_imageView.frame)+scale.x, CGRectGetHeight(_imageView.frame)+scale.y)];
[circleLayer setPath:[path CGPath]];
[circleLayer setStrokeColor:[[UIColor redColor] CGColor]];
[circleLayer setLineWidth:1.0f];
[circleLayer setFillColor:[[UIColor clearColor] CGColor]];
[[_imageView layer] addSublayer:circleLayer];
}

cornerRadius showing background colour in corners

To achieve the above design I use the below code. Every thing is perfect.
for(....)
{
CALayer *layer=[CALayer layer];
[layer setFrame:CGRectMake(xAxis, 2.0f, width, height)];
[layer setBackgroundColor:[self getColor:colorId]];
[[self layer] addSublayer:layer];
}
I have use cornerRadious for rounding the corner. And the problem is on corners it's shows the background colours little bit. Can anybody please suggest me what to do. I am using below code for cornerRadious. Thanks in advance.
[[vBarHolder layer] setCornerRadius:3.0f];
[[vBarHolder layer] setBorderColor:[[UIColor whiteColor] CGColor]];
[[vBarHolder layer] setBorderWidth:2.0f];
[[vBarHolder layer] setMasksToBounds:YES];
[vBarHolder setClipsToBounds:YES];
Your coloured views are overlapped by vBarHolder.
Modify the code as below.
for(....)
{
CALayer *layer=[CALayer layer];
[layer setFrame:CGRectMake(xAxis + 2, 2.0f + 2, width - 4 , height- 4)];
[layer setBackgroundColor:[self getColor:colorId]];
[[self layer] addSublayer:layer];
}
as the layers are having corner radius as 0 you are able to see in background.
Regards,
Amit

UICollectionViewCell with rounded corners AND drop shadow not working

I want my UICollectionViewCells to have rounded corners and drop shadows but I have run into a problem where it seems I can only have one or the other, but not both.
To just round the corners I use this code in the initialization of the cell:
CALayer *layer = [self layer];
[layer setCornerRadius:4];
[layer setRasterizationScale:[[UIScreen mainScreen] scale]];
[layer setShouldRasterize:YES];
To just add a drop shadow I use this code in the initialization of the cell:
CALayer *layer = [self layer];
[layer setMasksToBounds:NO];
[layer setRasterizationScale:[[UIScreen mainScreen] scale]];
[layer setShouldRasterize:YES];
[layer setShadowColor:[[UIColor blackColor] CGColor]];
[layer setShadowOffset:CGSizeMake(0.0f,0.5f)];
[layer setShadowRadius:8.0f];
[layer setShadowOpacity:0.2f];
[layer setShadowPath:[[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:layer.cornerRadius] CGPath]];
To try and have rounded corners and a drop shadow I use this code in the initialization of the cell:
CALayer *layer = [self layer];
[layer setMasksToBounds:NO];
[layer setCornerRadius:4];
[layer setRasterizationScale:[[UIScreen mainScreen] scale]];
[layer setShouldRasterize:YES];
[layer setShadowColor:[[UIColor blackColor] CGColor]];
[layer setShadowOffset:CGSizeMake(0.0f,0.5f)];
[layer setShadowRadius:8.0f];
[layer setShadowOpacity:0.2f];
[layer setShadowPath:[[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:layer.cornerRadius] CGPath]];
but this results in the drop shadow only.
Is this a bug or am I doing something wrong?
Works for me great:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
...
cell.layer.masksToBounds = YES;
cell.layer.cornerRadius = 6;
...
return cell;
}
If you place all your subviews into the UICollectionViewCell content view, which you probably are, you can set the shadow on the cell's layer and the border on the contentView's layer to achieve both results.
cell.contentView.layer.cornerRadius = 2.0f;
cell.contentView.layer.borderWidth = 1.0f;
cell.contentView.layer.borderColor = [UIColor clearColor].CGColor;
cell.contentView.layer.masksToBounds = YES;
cell.layer.shadowColor = [UIColor lightGrayColor].CGColor;
cell.layer.shadowOffset = CGSizeMake(0, 2.0f);
cell.layer.shadowRadius = 2.0f;
cell.layer.shadowOpacity = 1.0f;
cell.layer.masksToBounds = NO;
cell.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:cell.bounds cornerRadius:cell.contentView.layer.cornerRadius].CGPath;
Swift 4.0
cell.contentView.layer.cornerRadius = 2.0
cell.contentView.layer.borderWidth = 1.0
cell.contentView.layer.borderColor = UIColor.clear.cgColor
cell.contentView.layer.masksToBounds = true
cell.layer.shadowColor = UIColor.lightGray.cgColor
cell.layer.shadowOffset = CGSize(width: 0, height: 2.0)
cell.layer.shadowRadius = 2.0
cell.layer.shadowOpacity = 1.0
cell.layer.masksToBounds = false
cell.layer.shadowPath = UIBezierPath(roundedRect: cell.bounds, cornerRadius: cell.contentView.layer.cornerRadius).cgPath
There is tricky moment. Cutting corners and dropping shadow is mutually exclusive function in one layer. Dropping shadow is frame extension process, but corners is the process of masking to bounds.
Solution is in function separation. I recommend setup shadow for the cell layer, but cut corners for contentView layer of that cell.
I think I ran into a similar issue. My problem was that clipping in my subviews of the UICollectionViewCell didn't work properly with shadows and rounded borders. The exact same code worked just fine before when I had that view (as a standard UIView subclass though) in a UIScrollView.
So long story short, I moved all this setup from the initWithCoder to a later place after getting it from -dequeueReusableCellWithReuseIdentifier:forIndexPath:. Solved the problem for me. Seems like UICollectionViews are doing something I wouldn't expect to their cells' layers at some point?
If you are using a subclass to make the collection just make sure you do the following.
CALayer *layer = [self layer];
[layer setCornerRadius:_cornerRadius];
[layer setRasterizationScale:[[UIScreen mainScreen] scale]];
[layer setShouldRasterize:YES];
[layer setShadowColor:[[UIColor blackColor] CGColor]];
[layer setShadowOffset:CGSizeMake(0.0,4.0)];
[layer setShadowRadius:6.0f];
[layer setShadowOpacity:0.25];
[layer setShadowPath:[[UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:layer.cornerRadius] CGPath]];
self.contentView.layer.cornerRadius = _cornerRadius;
self.contentView.layer.borderWidth= _borderWidth;
self.contentView.layer.borderColor = _borderColor.CGColor;
self.contentView.backgroundColor = [UIColor whiteColor];
self.backgroundColor = [UIColor clearColor];
works like a charm.

Resources