I have to an arrow in a UIImageView. it may act like a transparent space in UIImageView. a sample image is attached and highlighted with yellow box.
Use mask,for example you have a 200*100 image
Code
CAShapeLayer * shapeLayer = [CAShapeLayer layer];
UIBezierPath * bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint:CGPointMake(0, 0)];
[bezierPath addLineToPoint:CGPointMake(0,100)];
[bezierPath addLineToPoint:CGPointMake(10,100)];
[bezierPath addLineToPoint:CGPointMake(20,90)];
[bezierPath addLineToPoint:CGPointMake(30, 100)];
[bezierPath addLineToPoint:CGPointMake(200,100)];
[bezierPath addLineToPoint:CGPointMake(200, 0)];
[bezierPath closePath];
shapeLayer.path = bezierPath.CGPath;
self.imageview.layer.mask = shapeLayer;
Note:The clip part is can still catch touch event or gesture as part of Imageview,you may rewrite pointInside to Ignore touch event
Edit About how it works
You just need to create any shape you like ,the about code I just create a shape like this,then use this shape to set mask
So,if you want make a right arrow,just create a shape like this
CAShapeLayer * shapeLayer = [CAShapeLayer layer];
UIBezierPath * bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint:CGPointMake(0, 0)];
[bezierPath addLineToPoint:CGPointMake(0,100)];
[bezierPath addLineToPoint:CGPointMake(170,100)];
[bezierPath addLineToPoint:CGPointMake(180,90)];
[bezierPath addLineToPoint:CGPointMake(190, 100)];
[bezierPath addLineToPoint:CGPointMake(200,100)];
[bezierPath addLineToPoint:CGPointMake(200, 0)];
[bezierPath closePath];
shapeLayer.path = bezierPath.CGPath;
Shape screenshot
So,what you need is
Figure out what shape you want(the outline mask shape)
Use bezierPath to draw
Set mask
Related
i want to obtain the progress bar like in the image below:
Striped loading progress bar with triangle at the end
Here is what i've done so far, with the help of the project from github https://github.com/iluuu1994/ITProgressBar-iOS, so here is what i attempted:
UIGraphicsBeginImageContextWithOptions(CGSizeMake(42, self.frame.size.height-10), NO, 0.f);
UIColor* color = [UIColor colorWithRed:251.0f/255.0f green:235.0f/255.0f blue:77.0f/255.0f alpha:1.0f];
UIBezierPath *bezierPath = [UIBezierPath new];
[bezierPath moveToPoint:CGPointMake(0.0, 0.0)];
[bezierPath addLineToPoint:CGPointMake(23, 0)];
[bezierPath addLineToPoint:CGPointMake(42, 29)];
[bezierPath addLineToPoint:CGPointMake(23, 70)];
[bezierPath addLineToPoint:CGPointMake(0, 70)];
[bezierPath addLineToPoint:CGPointMake(20, 29)];
[bezierPath addLineToPoint:CGPointMake(0, 0)];
[bezierPath closePath];
[color setFill];
[bezierPath fill];
}];
}
I tried to override the drawRect method from UIView but nothing seems to work, so i fought to apply a mask to the layer I'am using.
-(void)setTopRightCornerWithRadious:(CGFloat)radious View:(UIView*)vw
{
UIGraphicsGetCurrentContext();
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:vw.bounds byRoundingCorners:UIRectCornerTopRight cornerRadii:CGSizeMake(radious, radious)];
[maskPath closePath];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = vw.bounds;
maskLayer.path = maskPath.CGPath;
vw.layer.mask=maskLayer;
if (vw.layer.borderColor) {
UIColor *color=[UIColor colorWithCGColor:vw.layer.borderColor];
[color setStroke];
maskLayer.accessibilityPath.lineWidth=1.0f;
[maskLayer.accessibilityPath stroke];
}
}
-(void)setAllBorderForView:(UIView*)vw Color:(UIColor*)color Thickness:(CGFloat)thick
{
if (vw) {
vw.layer.borderWidth=thick;
vw.layer.borderColor=color.CGColor;
}
}
I wish to draw a border surrounded by these two button. I tried so many times with CAShapeLayer and UIBezierPath, but failed, may be I missed some thing. Some of them solve this problem using UIView, but I don't want that. I only want to solve the issues only by using the CAShapeLayer and/or UIBezierPath.
Here is my smaple code... WHere is my fault???? At very first i set the border, then I tried to set the corner. For few time may the border color exist or may not exist.
If you just need to have a border around the button, add stroke to the button bezier path.
- (void)drawRect: (CGRect)frame
{
UIBezierPath* rectangle2Path = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(x,y,widht,height) byRoundingCorners: UIRectCornerTopRight cornerRadii: CGSizeMake(17.25, 17.25)];
[rectangle2Path closePath];
[UIColor.grayColor setFill];
[rectangle2Path fill];
[UIColor.redColor setStroke];
rectangle2Path.lineWidth = 1;
[rectangle2Path stroke];
}
Or If you want to have space between the border and the button bezier path, then you should add two bezier paths. One for button, and another one for border.
- (void)drawRect: (CGRect)frame
{
UIBezierPath* rectanglePath = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(CGRectGetMinX(frame), CGRectGetMinY(frame), floor((CGRectGetWidth(frame)) * 1.00000 + 0.5), floor((CGRectGetHeight(frame)) * 1.00000 + 0.5)) byRoundingCorners: UIRectCornerTopRight cornerRadii: CGSizeMake(28, 28)];
[rectanglePath closePath];
[UIColor.redColor setStroke];
rectanglePath.lineWidth = 1;
[rectanglePath stroke];
UIBezierPath* rectangle2Path = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(CGRectGetMinX(frame) + 7, CGRectGetMinY(frame) + 8, 103, 62) byRoundingCorners: UIRectCornerTopRight cornerRadii: CGSizeMake(26, 26)];
[rectangle2Path closePath];
[UIColor.grayColor setFill];
[rectangle2Path fill];
}
In your custom button class you set this:
UIBezierPath outerPAth= [UIBezierPath bezirePath];
[[UIColor WhiteColor] setStroke];
outlinePath.lineWidth=5.0;
[outlinePath stroke];
i have a UIView with layout constraint (width:400, height:180) and i want to add a bezier inside the view.
my bezier is this:
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
// origin, height | left border
[bezierPath moveToPoint: CGPointMake(0, 20)];
// origin, height | left border
[bezierPath addLineToPoint: CGPointMake(0, _donationView.frame.size.height)];
// height, width | bottom border
[bezierPath addLineToPoint: CGPointMake(_donationView.frame.size.width , _donationView.frame.size.height)];
[bezierPath addLineToPoint: CGPointMake(_donationView.frame.size.width, 20)];
[bezierPath addLineToPoint: CGPointMake(_donationView.frame.size.width - 20, 20)];
[bezierPath addLineToPoint: CGPointMake(_donationView.frame.size.width - 30, 15)];
[bezierPath addLineToPoint: CGPointMake(_donationView.frame.size.width - 40, 20)];
[bezierPath addLineToPoint: CGPointMake(0, 20)];
[bezierPath closePath];
[UIColor.grayColor setFill];
[bezierPath fill];
[UIColor.blackColor setStroke];
bezierPath.lineWidth = 1;
[bezierPath stroke];
after creating bezier i pass to:
CAShapeLayer *shapeView = [[CAShapeLayer alloc] initWithLayer:_donationView.layer];
[shapeView setPath:bezierPath.CGPath];
_donationView.layer.mask = shapeView;
but the bezier goes to this CGRect(0, 0, 240, 128);
how can i have a CGRect of (0,0,400, 180)?
thanks guys
The problem is that you're doing this too soon, before donationView has attained its final size. Thus, when you read off its frame.size, you are getting the wrong result. You need to postpone the addition of the mask until after layout has taken place.
You can also run into further issues if donationView is ever resized later. It is quite annoying that a mask layer (or any layer) doesn't get to participate in autolayout. So if donationView is resized, you will have to remove this mask and create a new mask with the correct size and add it again.
I'm stumped here and need some assistance with this. For testing purposes I have a UIView that I draw into via drawRect (code below). I'm able to draw a circle with an specific angle and such but it's filled and closed. I need it to be open and stroked. I'm currently using UIBezierPath to do this but is there better way to do this? I can draw the open ended triangle like I want in UIBezierPath but I can't specify the angle that I need it to be (code below also). Any assistance with this would be much appreciated. Thanks.
The picture below is how I would like it to look when I draw it with a specific angle.
#import "AngleView.h"
#define DEGREES_TO_RADIANS(degrees) ((M_PI * degrees)/ 180)
#implementation AngleView
-(void)drawRect:(CGRect)rect {
UIBezierPath *aPath = [UIBezierPath bezierPathWithArcCenter:CGPointZero
radius:50
startAngle:0
endAngle:DEGREES_TO_RADIANS(45)
clockwise:NO];
[aPath fill];
}
#end
and here is how I can draw it without a specific angle.
UIBezierPath* bezierPath = [UIBezierPath bezierPath];
[bezierPath moveToPoint: CGPointMake(86.5, 33.5)];
[bezierPath addLineToPoint: CGPointMake(60.5, 62.5)];
[bezierPath addLineToPoint: CGPointMake(87.5, 62.5)];
[[UIColor blackColor] setStroke];
bezierPath.lineWidth = 1;
[bezierPath stroke];
Instead of trying draw one single line you can draw two separate originating from same point and you can give angle to one of them.
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextTranslateCTM(context, 0, 119.5); //here you can set originating point of line
CGContextRotateCTM(context, -45 * M_PI / 180); //Change Angle here -45
UIBezierPath* bezierPath = UIBezierPath.bezierPath;
[bezierPath moveToPoint: CGPointMake(0, 0)];
[bezierPath addCurveToPoint: CGPointMake(39, 0) controlPoint1: CGPointMake(39, 0) controlPoint2: CGPointMake(39, 0)];
[UIColor.blackColor setStroke];
bezierPath.lineWidth = 1;
[bezierPath stroke];
CGContextRestoreGState(context);
//Second UIBezierPath with 0 angle
context = UIGraphicsGetCurrentContext();
UIBezierPath* bezier2Path = UIBezierPath.bezierPath;
[bezier2Path moveToPoint: CGPointMake(0, 119.5)];
[bezier2Path addCurveToPoint: CGPointMake(38.5, 119.5) controlPoint1: CGPointMake(38.5, 119.5) controlPoint2: CGPointMake(38.5, 119.5)];
[UIColor.blackColor setStroke];
bezier2Path.lineWidth = 1;
[bezier2Path stroke];
CGContextRestoreGState(context);
}
I am trying to create a button with a triangle icon/shape in it. I have created the triangle in Paintcode then copied the beizer path and added it to the button layer as below.
-(void)setupShowHideRouteButton {
UIBezierPath* bezierPath = UIBezierPath.bezierPath;
[bezierPath moveToPoint: CGPointMake(10.5, 8.5)];
[bezierPath addCurveToPoint: CGPointMake(40.5, 8.5) controlPoint1: CGPointMake(39.5, 8.5) controlPoint2: CGPointMake(40.5, 8.5)];
[bezierPath addLineToPoint: CGPointMake(26.39, 22.3)];
[bezierPath addLineToPoint: CGPointMake(25.2, 23.5)];
[bezierPath addLineToPoint: CGPointMake(10.5, 8.5)];
[UIColor.blackColor setStroke];
bezierPath.lineWidth = 1;
[bezierPath stroke];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.frame = self.showHideRouteViewBtn.bounds;
shapeLayer.path = bezierPath.CGPath;
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.strokeColor = [UIColor blackColor].CGColor;
shapeLayer.lineWidth = 2;
[self.showHideRouteViewBtn.layer addSublayer:shapeLayer];
}
However, this does not appear to work. I am setting the background color of the UIButton so I know the frame is correct and outlet working as expected it is just not adding the shape?
Second Approach
UIBezierPath* bezierPath = UIBezierPath.bezierPath;
[bezierPath moveToPoint: CGPointMake(10.5, 8.5)];
[bezierPath addCurveToPoint: CGPointMake(40.5, 8.5) controlPoint1: CGPointMake(39.5, 8.5) controlPoint2: CGPointMake(40.5, 8.5)];
[bezierPath addLineToPoint: CGPointMake(26.39, 22.3)];
[bezierPath addLineToPoint: CGPointMake(25.2, 23.5)];
[bezierPath addLineToPoint: CGPointMake(10.5, 8.5)];
[UIColor.blackColor setStroke];
bezierPath.lineWidth = 1;
[bezierPath stroke];
// Create a mask layer and the frame to determine what will be visible in the view.
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
CGRect maskRect = self.showHideRouteViewBtn.bounds;
// Create a path with the rectangle in it.
CGPathRef path = CGPathCreateWithRect(maskRect, NULL);
// Set the path to the mask layer.
maskLayer.path = bezierPath.CGPath;
// Release the path since it's not covered by ARC.
CGPathRelease(path);
// Set the mask of the view.
self.showHideRouteViewBtn.layer.mask = maskLayer;
This did not work either.
Try the following:
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.frame = self.showHideRouteViewBtn.bounds;
shapeLayer.path = bezierPath.CGPath;
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.strokeColor = [UIColor blackColor].CGColor;
shapeLayer.lineWidth = 2;
self.showHideRouteViewBtn.layer.mask = shapeLayer;