Adding Rounded Corners to UIView without breaking interactions. - ios

This answer works great, Adding Rounded Corners to only top of UITableView? except my UIBarButtonItems are no longer clickable. My guess is that the mask is now sitting on top of the buttons breaking the interaction.
Does anyone have any ideas to implement this without interfering with the rest of the view?

Have you tried just masking your tableView's layer:
CAShapeLayer * maskLayer = [CAShapeLayer layer];
maskLayer.path = [UIBezierPath bezierPathWithRoundedRect: self.bounds byRoundingCorners: UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii: (CGSize){10.0, 10.}].CGPath;
self.tableView.layer.mask = maskLayer;
or just using:
self.tableView.layer.cornerRadius = 10.0
for the whole table

Related

How to curve UIVew only top corner and not whole view in Objective C?

I am new in iOS and I am facing problem regarding to curve UIView. I want to curve the radius of the top of UIView like this in the Image
As you can see the screenshot of my work view.
I am using code like this
UIBezierPath *maskPath = [UIBezierPath
bezierPathWithRoundedRect:ViewSwapMyWork.bounds
byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight)
cornerRadii:CGSizeMake(70, 70)
];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = ViewSwapMyWork.bounds;
maskLayer.path = maskPath.CGPath;
ViewSwapMyWork.layer.mask = maskLayer;
First your view should have the same height and width means it should be square, then you can do like this,
[ViewSwapMyWork.layer setCornerRadius:ViewSwapMyWork.frame.size.width/2];
[ViewSwapMyWork.layer setMasksToBounds:YES];

UIBezierPath bezierPathWithRoundedRect wrong rounding

I'm trying to round the chat bubbles by applying bezierPathWithRoundedRect to them. Everything works almost perfect. But for some strange reason in some cases one of the corners seems to me much bigger than others. Why it happens and hou to avoid it?
My code:
bubbleContainer.layer.cornerRadius = 6.0;
UIRectCorner cornersOut = (UIRectCornerTopLeft | UIRectCornerTopRight | UIRectCornerBottomLeft);
UIRectCorner cornersIn = (UIRectCornerTopLeft | UIRectCornerTopRight | UIRectCornerBottomRight);
UIRectCorner corners = isOutMessage ? cornersOut : cornersIn;
UIBezierPath * maskPath = [UIBezierPath bezierPathWithRoundedRect:bubbleContainer.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(17.0, 17.0)];
CAShapeLayer * maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = bubbleContainer.bounds;
maskLayer.path = maskPath.CGPath;
bubbleContainer.layer.mask = maskLayer;
As you can see, bubbles with text "111" and "1111" have a different top right corner. There is no other masking for bubbles and after applying tha mask bubbles do not resize.

Rounded Corners only for the bottoms edges of UITableView

I'm using the below code to make rounded corners only for the bottom edges of tableView
CALayer *capa = self.patientTableView.layer;
//Round
CGRect bounds = capa.bounds;
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:bounds
byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight)
cornerRadii:CGSizeMake(10.0, 10.0)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = bounds;
maskLayer.path = maskPath.CGPath;
[capa addSublayer:maskLayer];
capa.mask = maskLayer;
This code works fine, but the tableview is not showing up the contents below its frame height (but it scrolls to its offset.y).
You can fix this by putting the table view inside a UIView, and then apply the mask to that container view. That way the mask will not move with the contentOffset of the table view.

Setting mask layer on UITableViewCell's subview overrides Auto Layout constraints

I have a UITableViewCell with multiple subviews. One of the subviews is a UILabel and the cell's height is dynamically sized based on the amount of text in the UILabel. This works perfectly.
I have another subview in the cell that has constraints as well. This subview is always supposed to have the exact same height as the cell. This works perfectly as well.
However, I run into problems when trying to set a mask layer on that subview. The mask layer works correctly, but then the subview's height is wrong and it is not the same height as the cell.
Here is my mask layer code:
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.mySubview.bounds
byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight | UIRectCornerBottomLeft | UIRectCornerBottomRight)
cornerRadii:CGSizeMake(10, 10)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = self.mySubview.bounds;
maskLayer.path = maskPath.CGPath;
self.mySubview.layer.mask = maskLayer;
I have been doing research and trying to find a way to fix this so I can both set the mask layer and have the subview have it's correct height but I haven't been able to get it to work.
I have seen this solution recommended several times now:
[self setNeedLayout];
[self layoutIfNeeded];
// Customize cell after here
But this doesn't work for me either. Is there a way for me to know when the Auto Layout constraints have been applied so that I can then apply the mask layer afterwards?
The mask layer code is really simple, it uses the bounds of the subview, and the bounds are off because it's using the bounds that exist before the constraints have been applied and the subview has the correct height. At least I think I'm understanding that correctly.
I finally got it. I'm not sure if this is the correct place to put this or if it might cause performance problems, but so far it works perfectly:
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.mySubview.bounds
byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight | UIRectCornerBottomLeft | UIRectCornerBottomRight)
cornerRadii:CGSizeMake(10, 10)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = self.mySubview.bounds;
maskLayer.path = maskPath.CGPath;
self.mySubview.layer.mask = maskLayer;
}
I had to override drawRect: in my UITableViewCell subclass and set the mask layer there.
I have had same problem and doing things in - (void)drawRect:(CGRect)rect does the work but it could be costly in terms of performance.
You can call your clipping or shadow methods in perform selector
[self performSelector:#selector(<your drawing method>) withObject:nil afterDelay:0.0000001 ];//a very low delay

Minimize off-screen rendering when using CAShapeLayer

Pretty standard setup: VC view has top corners rounded via CAShapeLayer with UIBezierPath, like this:
UIBezierPath *cornerPath = [UIBezierPath bezierPathWithRoundedRect:self.view.bounds
byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight
cornerRadii:CGSizeMake(4, 4)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = self.view.bounds;
maskLayer.path = cornerPath.CGPath;
self.view.layer.mask = maskLayer;
While this works, it leads to the whole view being rendered offscreen, surely there should be a way to at least minimize that rendering to corners, or even get rid of it?

Resources