Navigation bar stops working after applying a layer mask - cocoa-touch

I used a CAShapeLayer to create a mask, which I gave round corners at the top left/right then applied it to my navigationController's navigationBar.
It works like a charm, but I've now noticed I can't use buttons on the navigation bar!
Here's the code I use (in viewDidLoad):
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.navigationController.navigationBar.bounds
byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight
cornerRadii:CGSizeMake(6.0, 6.0)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = self.navigationController.navigationBar.bounds;
maskLayer.path = maskPath.CGPath;
self.navigationController.navigationBar.layer.mask = maskLayer;

You would need to set the buttons programmatically after setting the layer mask.

Related

Draw line CAShapeLayer layer color by rect region

The Problem I facing right now is that after I draw the dots and lines by CAShapeLayer, I need to modify both of their colors by changing with different for rect regions. The regions I set right now have four portions, and following are the sample codes:
- (void)drawChartWithRecord:(Chart *)Chart
lineWidth:(CGFloat)lineWidth
radius:(CGFloat)radius
interval:(CGFloat)interval
rect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
float start_angle = 0;
float end_angle = (float) (2 * M_PI);
CAShapeLayer *avg = [CAShapeLayer layer];
avg.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(X,Y) radius:radius startAngle:start_angle endAngle:end_angle clockwise:YES].CGPath;
CGContextMoveToPoint(context, X, Y);
CGContextAddLineToPoint(context, pastX, pastY);
CGContextSetStrokeColorWithColor(context, LINE_COLOR);
CGContextSetLineWidth(context, lineWidth);
CGContextStrokePath(context);
[self.layer addSublayer:avg];
}
Upon with the line and dots codes; however, I didn't find out any method to import the rect to the same CAShapeLayer. If I make a new layer as
CAShapeLayer *mask = [CAShapeLayer layer];
There would be a problem that If I use
[self.layer addSublayer:mask];
Two of the sublayers would mix, and I don't want to change my background color.
Thanks for everyone's help : )
Unfortunately, I was wrong about my question.
The thing I want could be easy to solve by the CAGradientLayer & CAShapeLayer. Once you finish your own CAShapeLayer, by using
[self.gradientLayer setMask:avgCircle];
you can easily add the the your own gradient color to the line shape CAShapeLayer
Be sure add addSublayer: for both CAGradientLayer & CAShapeLayer

Draw Border along the cutting edges of a UIView

I have a UIView with rounded corners along TopLeft and Bottom Right corner sides implement using this code.
CGFloat cornerRadius = _emailContainerView.frame.size.height/2;
CGRect bounds = _emailContainerView.bounds;
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:bounds
byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerBottomRight)
cornerRadii:CGSizeMake(cornerRadius, cornerRadius)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = bounds;
maskLayer.path = maskPath.CGPath;
_emailContainerView.layer.mask = maskLayer;
But whenever i tried to draw a border either on the _emailContainerView.layer.borderWidth it shows the border but not along the cutting edges. It just remover the border from the rounded corner sides.
I want to draw the border right along the cutting edges is their any simple way to do that?

How to Animate a UIBezierPath

i would like to animate a UIBezierPath of a rect to a triangle one, not to animate a view on a path but animate the path itself so it morphs from one shape to another. the path is added to a CALayer
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.fillColor = [[UIColor whiteColor] CGColor];
maskLayer.path = [self getRectPath];
-(CGPathRef)getTrianglePath
{
UIBezierPath* triangle = [UIBezierPath bezierPath];
[triangle moveToPoint:CGPointZero];
[triangle addLineToPoint:CGPointMake(width(self.view),0)];
[triangle addLineToPoint:CGPointMake(0, height(self.view))];
[triangle closePath];
return [triangle CGPath];
}
-(CGPathRef)getRectPath
{
UIBezierPath*rect = [UIBezierPath bezierPathWithRect:self.view.frame];
return [rect CGPath];
}
I am not an expert on CoreAnimation but you can define a CABasicAnimation as follows
CABasicAnimation *morph = [CABasicAnimation animationWithKeyPath:#"path"];
morph.duration = 5;
morph.toValue = (id) [self getTrianglePath];
[maskLayer addAnimation:morph forKey:nil];
The first line states that you want to define an animation that changes the path property of the layer. The second line states that the animation takes five seconds and the third line gives the final state of the animation. Finally, we add the animation to the layer. The key is a unique identifier for the animation, that is, if you add two animations with the same key only the last one is considered. This key can also be used to override so called implicit animations. There are a couple of properties of a CALayer that are animated by default. More precisely, if you change one of these properties the change will be animated with a duration of 0.25.

move uiimage inside a bezier curve

I have drawn a circle using bezier curve, I am using this circle as a mask to a uiimage view. Now, how can i move the image inside the circle without moving the circle using touches.
here is my code.
CAShapeLayer *maskLayer = [CAShapeLayer layer];
aPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(220, 220)
radius:170
startAngle:0
endAngle:DEGREES_TO_RADIANS(360)
clockwise:YES];
maskLayer.backgroundColor = [[UIColor clearColor] CGColor];
maskLayer.path = [aPath CGPath];
maskLayer.masksToBounds=YES;
imageView1.layer.mask = maskLayer;
[self.view addSubview:imageView1];
The coordinates of the mask is the same as the coordinates of your views layer = it moves along with the view.
You can add the image inside another view and mask that view instead. Then you can move the image inside the other view and the mask will stay the same.
Alternatively (but really the same solution) you could keep the mask on that layer and add a sublayer with the image and move that instead.

How to restore rounded corners for a UITableViewCell filled with an image?

I have a UITableViewCell, and I want to use the image property to fill it with an image. When it is first in a grouped UITableView, I want it to have the standard rounded corners.
Unfortnately, the image fills the rounded corners as well.. Is there any way to retain them without using a transparent image?
You can round the corners of any view programmatically by using its layer property. If you play about with the cornerRadius property of the layer you should be able to achieve the results you want.
#include <QuartzCore/QuartzCore.h>
UIImage *myImage = [UIImage imageNamed:#"image.png"];
UIImageView *imgView = [[UIImageView alloc] initWithImage:myImage];
imgView.layer.cornerRadius = 10.0;
If you just want to round some of the corners, you should look at the UIBezierPath API and use the path to mask your image. This isn't tested but it should point you in the right direction:
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:cell.bounds
byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight
cornerRadii:CGSizeMake(10.0, 10.0)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = imageView.frame;
maskLayer.path = path;
imageView.layer.mask = maskLayer;
I just made my non-transparent images have the rounded corner. Take a screen shot to get the dimensions of the rounded corner then use that as the basis for your image.