11

I have a custom button that I want to make top-left border of it look like normal round rectangle.

I found code that makes all corners round:

_myButton.layer.cornerRadius = 8;
_myButton.layer.borderWidth = 0.5;
_myButton.layer.borderColor = [UIColor grayColor].CGColor;
_myButton.clipsToBounds = YES;

enter image description here

How can I fix the code to make it round just in the top-left side?


Edit:

_myButton.layer.borderWidth = 2;
_myButton.layer.borderColor = [UIColor blackColor].CGColor;

UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:_myButton.bounds
                                                    byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight
                                                        cornerRadii:CGSizeMake(7.0, 7.0)];

CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];

maskLayer.frame = _myButton.bounds;
maskLayer.path = maskPath.CGPath;
_myButton.layer.mask = maskLayer;
[maskLayer release];

This code does not work. The whole button disappears.

Juan Boero
  • 6,281
  • 1
  • 44
  • 62
Ali
  • 9,800
  • 19
  • 72
  • 152
  • Here is a similar question/answer on how you can use a UIBezierPath to tell which corners to keep/mask on a UIView: http://stackoverflow.com/questions/10995226/how-to-make-a-half-rounded-top-corner-rounded-texview-with-border – Brayden Oct 08 '12 at 22:06
  • I used the code provided there. but it does not work. I added the code to the end of question. can you help me @Brayden? – Ali Oct 08 '12 at 22:45

2 Answers2

23

You almost got it, but, after building your CAShapeLayer, use it to add itself as a sublayer of your button's layer, not as an alpha mask to hide some parts of your button (in that case the corners).

UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(10,300,300,40);
[button setTitle:@"Hey" forState:(UIControlStateNormal)];
[button setTitleColor:[UIColor blueColor] forState:(UIControlStateNormal)];

UIBezierPath *shapePath = [UIBezierPath bezierPathWithRoundedRect:button.bounds
                                                byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight
                                                      cornerRadii:CGSizeMake(7.0, 7.0)];

CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.frame = button.bounds;
shapeLayer.path = shapePath.CGPath;
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.strokeColor = [UIColor blackColor].CGColor;
shapeLayer.lineWidth = 2;
[button.layer addSublayer:shapeLayer];

[self.view addSubview:button];
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
AliSoftware
  • 32,623
  • 6
  • 82
  • 77
  • thanks, look at this line : `[_myButton.layer addSublayer:shapePath];` Do you mean `shapeLayer`instead of shapePath? – Ali Oct 08 '12 at 23:14
  • 1
    that's what I meant sry. What do yo mean by "did not work" what did it look like? – AliSoftware Oct 08 '12 at 23:23
  • It does not show the borders. I just can see the button text. No borders. – Ali Oct 08 '12 at 23:28
  • I don't get it, I just tried it in a sample project and it worked I got the border around… – AliSoftware Oct 08 '12 at 23:39
  • So strange, can you send the project to me? this is my email: alirezai83@yahoo.com – Ali Oct 08 '12 at 23:42
  • Are you sure you did create the layer after setting the button's frame? Maybe when you created your `shapePath` and set the `CAShapeLayer`'s `frame` you used a wrong value because your `_myButton`'s `frame` was not set to its proper value yet? – AliSoftware Oct 08 '12 at 23:44
  • Actually I just put my code really quickly in the `viewDidLoad` of my current project, but I just copy-pasted what I wrote. I'll add every surrounding line of code in my answer – AliSoftware Oct 08 '12 at 23:47
  • Yes I am. I just copied your code, but if it works for you, then please send me the project. I really appreciate. – Ali Oct 08 '12 at 23:48
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/17721/discussion-between-ali-and-alisoftware) – Ali Oct 08 '12 at 23:48
1
CAShapeLayer * positiveCorner = [CAShapeLayer layer];
positiveCorner.path = [UIBezierPath bezierPathWithRoundedRect: self.button.bounds
                                            byRoundingCorners: UIRectCornerTopRight | UIRectCornerBottomRight
                                                  cornerRadii: (CGSize){5, 5}].CGPath;

self.button.layer.mask = positiveCorner;
Leonardo Cavalcante
  • 1,274
  • 1
  • 16
  • 26