I'm customizing a UITextfield to look like a UISearchbar.
I do something like
self.back_textfield = [[UITextField alloc]initWithFrame:CGRectMake(5, 7, 310, 30)];
[self.back_textfield setBorderStyle:UITextBorderStyleRoundedRect];
self.back_textfield.layer.cornerRadius = 15.0;
But I see this:
As you can see the inner shadow doesn't follow the border.
I guess background on a UITextField is an Image, so it no follow to your corner radius.
Creating inner shadow is tricky in iOS. You have 2 options.
1) Use image as background for UITextField
2) Set the shadow programmatically (but it look less attractive than option 1).
Here is the code for setting rounded inner shadow for textfield with solution from #Matt Wilding
_textField.layer.cornerRadius = 10.0f;
CAShapeLayer* shadowLayer = [CAShapeLayer layer];
[shadowLayer setFrame:_textField.bounds];
// Standard shadow stuff
[shadowLayer setShadowColor:[[UIColor colorWithWhite:0 alpha:1] CGColor]];
[shadowLayer setShadowOffset:CGSizeMake(0.0f, 0.0f)];
[shadowLayer setShadowOpacity:1.0f];
[shadowLayer setShadowRadius:4];
// Causes the inner region in this example to NOT be filled.
[shadowLayer setFillRule:kCAFillRuleEvenOdd];
// Create the larger rectangle path.
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectInset(_textField.bounds, -42, -42));
// Add the inner path so it's subtracted from the outer path.
// someInnerPath could be a simple bounds rect, or maybe
// a rounded one for some extra fanciness.
CGPathRef someInnerPath = [UIBezierPath bezierPathWithRoundedRect:_textField.bounds cornerRadius:10.0f].CGPath;
CGPathAddPath(path, NULL, someInnerPath);
CGPathCloseSubpath(path);
[shadowLayer setPath:path];
CGPathRelease(path);
[[_textField layer] addSublayer:shadowLayer];
CAShapeLayer* maskLayer = [CAShapeLayer layer];
[maskLayer setPath:someInnerPath];
[shadowLayer setMask:maskLayer];
Don't forget to import
#import <QuartzCore/QuartzCore.h>
add QuartzCore FrameWork to your project
And add it in your .m file
#import <QuartzCore/QuartzCore.h>
and use
self.back_textfield.layer.borderWidth = 1.0f; // set as you per your requirement
self.back_textfield.layer.cornerRadius = 5.2f; // set as you per your requirement
Related
I need to add several kinds of effects on a UIView with rounding its top left and top right corners, white border and dark shadow on its rounded corner curve like the picture below:
I created a MSHTablePaneCell class inherited from UIView and then overrided its drawRect method:
static const CGFloat kCornerRadius = 15;
#implementation MSHTablePaneCell ()
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:(UIRectCornerTopLeft |UIRectCornerTopRight) cornerRadii:CGSizeMake(kCornerRadius, kCornerRadius)];
// 1. mask round corner
CAShapeLayer *roundLayer = [CAShapeLayer layer];
roundLayer.path = path.CGPath;
roundLayer.frame = self.bounds;
// roundLayer.cornerRadius = 10.0;
self.layer.mask = roundLayer;
// 2. add border to round corner curve
UIBezierPath *topCurvepath = [UIBezierPath bezierPath];
[topCurvepath moveToPoint:CGPointMake(0, kCornerRadius)];
[topCurvepath addQuadCurveToPoint:CGPointMake(kCornerRadius, 0) controlPoint:CGPointMake(0, 0)];
[topCurvepath addLineToPoint:CGPointMake(CGRectGetWidth(self.frame)-kCornerRadius, 0)];
[topCurvepath addQuadCurveToPoint:CGPointMake(CGRectGetWidth(self.frame), kCornerRadius) controlPoint:CGPointMake(CGRectGetWidth(self.frame), 0)];
CAShapeLayer *topBorderLayer = [CAShapeLayer layer];
topBorderLayer.lineWidth = 4.0;
topBorderLayer.borderColor = [UIColor redColor].CGColor;
topBorderLayer.path = topCurvepath.CGPath;
[self.contentView.layer addSublayer:topBorderLayer];
}
#end
However, with code above, I just got the final picture like below:
No matter which property I set, the topCurvePath just displayed with black background color, how I can fix this problem? Thanks in advance~
topBorderLayer.fillColor = [UIColor yourColor].CGColor
I am new to IOS development, try to create top rounded corner label
by following link
How do I round only the top two corners of a UILabel?
But after applying the mask, the whole label cannot be seen, Any clue?
Here is my code.
#synthesize title;
- (void)viewDidLoad
{
[super viewDidLoad];
title.layer.borderColor=[[UIColor blueColor]CGColor];
title.layer.borderWidth=2;
UIBezierPath *maskPath;
maskPath = [UIBezierPath bezierPathWithRoundedRect:title.bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight) cornerRadii:CGSizeMake(10.0f, 10.0f)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame=title.bounds;
maskLayer.path = maskPath.CGPath;
title.layer.mask = maskLayer;
}
EDITED
Tried the suggestion to create the label in program, the layout become
https://docs.google.com/file/d/0B60xg2ZCEjOqeTBEWG92N0NodFU/edit?usp=sharing
The corner disappear and I still want to set the mask the "title" labal?
EDITED
Finally give up, for others benefit,I wrap the label in uiview , map the uiview to a class (i.e. Myview.m), and put the same code in method "- (void)drawRect:(CGRect)rect{}" in "Myview.m". The display showed as what I want!.
I'm not sure if this is your problem because you didn't show how the title label is created, but if you're creating it in code, you need to be sure to alloc/init the label, as well as give it a frame and then add it as a subview of its superview.
title = [[UILabel alloc] initWithFrame:CGRectMake(100.0f, 100.0f, 60.0f, 30.0f)];
title.layer.borderColor=[[UIColor blueColor]CGColor];
title.layer.borderWidth=2;
UIBezierPath *maskPath;
maskPath = [UIBezierPath bezierPathWithRoundedRect:title.bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight) cornerRadii:CGSizeMake(10.0f, 10.0f)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame=title.bounds;
maskLayer.path = maskPath.CGPath;
title.layer.mask = maskLayer;
[self.view addSubview:title];
first of all my advice is don't use "title" as a UILabel name because all UIViewController has a property that name is title.
After changing label name and sure IBOutlet is connected add this code:
lblTitle.layer.masksToBounds = YES;
I just figure out if you create a label on storyboard you dont need to alloc again. I wrote this code and it works;
_L_corner.layer.borderColor =[[UIColor blueColor] CGColor];
_L_corner.layer.borderWidth = 5.0f;
_L_corner.layer.cornerRadius = 3.0f;
Finally give up, for others benefit, and used another work around:-
1) wrap the label in uiview ,
2) map the uiview to a class (i.e. Myview.m),
3) put the same code in method
- (void)drawRect:(CGRect)rect{
title.layer.borderColor=[[UIColor blueColor]CGColor];
title.layer.borderWidth=2;
UIBezierPath *maskPath;
maskPath = [UIBezierPath bezierPathWithRoundedRect:title.bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight) cornerRadii:CGSizeMake(10.0f, 10.0f)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame=title.bounds;
maskLayer.path = maskPath.CGPath;
title.layer.mask = maskLayer;
}
in "Myview.m".
The display showed as what I want!
I am trying to round the bottom two corners of a UIView, and have the layer’s border show up rounded as well. I am currently doing:
UIRectCorners corners = UIRectCornerBottomLeft | UIRectCornerBottomRight;
CGSize radii = CGSizeMake(kThisViewCornerRadius, kThisViewCornerRadius);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:myView.bounds
byRoundingCorners:corners
cornerRadii:radii];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
[maskLayer setPath:path.CGPath];
myView.layer.mask = maskLayer;
This works fine for normal views. However, myView’s layer has its borderColor and borderWidth set, and as you can see from the screenshot, the layer’s border is not getting rounded:
I also tried subclassing UIView and returning [CAShapeLayer layer] from +[Class layerClass], and setting up the view’s layer as a shape layer, but the border ended up beneath the view’s subviews.
Is it possible to round some of a view’s corners, round the view’s layer’s border, and clip the subviews underneath the layer’s border?
Note that this is not about how to round some corners and not others, but rather how to get the stroke to behave correctly.
I figured out a new way of thinking about it, thanks to David Rönnqvist’s comment.
I was trying to do the corner rounding and the stroke all in one layer. Instead, I broke it up into two layers: one to mask the view’s layer to round the corners, and the other in a view to add the stroke.
UIView *containerView = [[UIView alloc] initWithFrame:someFrame];
UIRectCorners corners = UIRectCornerBottomLeft | UIRectCornerBottomRight;
CGSize radii = CGSizeMake(kThisViewCornerRadius, kThisViewCornerRadius);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:myView.bounds
byRoundingCorners:corners
cornerRadii:radii];
// Mask the container view’s layer to round the corners.
CAShapeLayer *cornerMaskLayer = [CAShapeLayer layer];
[cornerMaskLayer setPath:path.CGPath];
containerView.layer.mask = cornerMaskLayer;
// Make a transparent, stroked layer which will dispay the stroke.
CAShapeLayer *strokeLayer = [CAShapeLayer layer];
strokeLayer.path = path.CGPath;
strokeLayer.fillColor = [UIColor clearColor].CGColor;
strokeLayer.strokeColor = [UIColor redColor].CGColor;
strokeLayer.lineWidth = 2; // the stroke splits the width evenly inside and outside,
// but the outside part will be clipped by the containerView’s mask.
// Transparent view that will contain the stroke layer
UIView *strokeView = [[UIView alloc] initWithFrame:containerView.bounds];
strokeView.userInteractionEnabled = NO; // in case your container view contains controls
[strokeView.layer addSublayer:strokeLayer];
// configure and add any subviews to the container view
// stroke view goes in last, above all the subviews
[containerView addSubview:strokeView];
Zev Eisenberg's answer is the right one.
Although I prefer:
[self.layer addSublayer:strokeLayer];
instead of creating and adding a subview:
CGSize radii = CGSizeMake(radius, radius);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds
byRoundingCorners:corners
cornerRadii:radii];
// Mask the container view’s layer to round the corners.
CAShapeLayer *cornerMaskLayer = [CAShapeLayer layer];
[cornerMaskLayer setPath:path.CGPath];
self.layer.mask = cornerMaskLayer;
// Make a transparent, stroked layer which will dispay the stroke.
CAShapeLayer *strokeLayer = [CAShapeLayer layer];
strokeLayer.path = path.CGPath;
strokeLayer.fillColor = [UIColor clearColor].CGColor;
strokeLayer.strokeColor = color.CGColor;
strokeLayer.lineWidth = 2; // the stroke splits the width evenly inside and outside,
// but the outside part will be clipped by the containerView’s mask.
[self.layer addSublayer:strokeLayer];
Here is the small code. Alloc init a view and send to this method to get corners rounded. You can optionally round any of the corners u want. Also give shadow stroke color.
-(void) setMaskTo:(UIView*)view byRoundingCorners:(UIRectCorner)corners withColor: (UIColor*) color
{
UIBezierPath* rounded = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(9.0, 9.0)];
CAShapeLayer* shape = [[[CAShapeLayer alloc] init] autorelease];
[shape setPath:rounded.CGPath];
shape.strokeColor = [[UIColor grayColor] CGColor];
view.backgroundColor=color;
view.layer.mask = shape;
}
Call the method like this.
[self setMaskTo:ABCView byRoundingCorners:UIRectCornerAllCorners withColor:[UIColor greenColor]];
I have a UIView. I need to make only it's top left and top right corners rounded and also to have a 1 point border width.
Any idea?
Thanks
Try this:
#import <QuartzCore/QuartzCore.h>
view.layer.cornerRadius = 8.0;
view.layer.borderWidth = 1.0;
view.layer.borderColor = [UIColor blueColor].CGColor;
however, it'll make all of your corners rounded. If you don't want this, there are two options:
Draw the rounded corner yourself using CoreGraphics (How to draw a rounded rectangle in Core Graphics / Quartz 2D?) or
Use a mask (CALayer's #property mask here: http://developer.apple.com/library/ios/#DOCUMENTATION/GraphicsImaging/Reference/CALayer_class/Introduction/Introduction.html)
UIView With top left,right rounded corners and shadow
#import <QuartzCore/QuartzCore.h>
backView.layer.shadowColor=[UIColor blackColor].CGColor;
backView.layer.masksToBounds = NO;
backView.layer.shadowOffset = CGSizeMake(0.0f, 1.0f);
backView.layer.shadowRadius = 3;
backView.layer.shadowOpacity = 0.8;
CGFloat radius = 20.0;
CGRect maskFrame = self.backView.bounds;
maskFrame.size.height += radius;
CALayer *maskLayer1 = [CALayer layer];
maskLayer1.cornerRadius = radius;
maskLayer1.backgroundColor = [UIColor blackColor].CGColor;
maskLayer1.frame = maskFrame;
self.backView.layer.mask = maskLayer1;
you can achieve this using beizer path like this -
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(5.0, 5.0)];
[maskPath setLineWidth:1.0];
//to give stroke color
[[UIColor colorWithRed:186.0/255.0 green:186.0/255.0 blue:186.0/255.0 alpha:1.0] setStroke];
//to color your border
[[UIColor colorWithRed:242.0/255.0 green:240.0/255.0 blue:240.0/255.0 alpha:1.0] setFill];
[maskPath fill];
[maskPath stroke];
Use CALayer's and try this tutorial more more information. http://nachbaur.com/blog/rendering-views-using-calayer-part-1
A very simple and quick solution:
set the corner radius so that it draws all four corners rounded in the normal way
for each corner that you don't want rounded:
create a small square UIView with side equal to the corner radius
add it as subview of the main view (the one with the rounded corners)
position it so that it sits exactly over the corner
set its background color to be the same as the main view's background
Not necessarily the most elegant solution, but only takes a minute to code it up!
Take a look at the following image:
As you can see the edges are sharp rectangle and they are coming out of the rounded corner button. How can I not show the edges and only show the round button?
UPDATE (Solution):
I used the following code to achieve the round corners:
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.stopButton.bounds
byRoundingCorners:UIRectCornerAllCorners
cornerRadii:CGSizeMake(12.0, 12.0)];
// Create the shape layer and set its path
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = self.stopButton.bounds;
maskLayer.path = maskPath.CGPath;
// Set the newly created shape layer as the mask for the image view's layer
self.stopButton.layer.mask = maskLayer;
NEW PROBLEM:
This code gives me the error on the startButtonRound.layer.cornerRadius line.
UIButton *roundStartButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
roundStartButton.frame = CGRectMake(10, 10, 100, 20);
[roundStartButton setBackgroundImage:[UIImage imageNamed:#"green_gradient.jpg"] forState:UIControlStateNormal];
roundStartButton.layer.cornerRadius = 12.0;
UIBarButtonItem *startButton = [[UIBarButtonItem alloc] initWithCustomView:roundStartButton];
You could do this with CALayer alone:
CALayer *myLayer = [CALayer layer];
[myLayer setMasksToBounds:YES];
[myLayer setCornerRadius:5.0f];
[myLayer setBorderWidth:1.0f];
[myLayer setBorderColor: [[UIColor blackColor] CGColor]];
[myLayer setBackgroundColor: [[UIColor whiteColor] CGColor]];
You'll also want to include the QuartzCore framework and include the frameworks header in your own.
#include <QuartzCore/QuartzCore.h>
Hope this helps
Tim
I think all that can be accomplished with:
self.stopButton.layer.cornerRadius = 12.0;
But did you try
self.stopButton.opaque = NO;
self.stopButton.backgroundColor = [UIColor clearColor];
?
form the look of the image you have set your UIButton bckground color to 'White'. Make it 'Clear Color'.