How to have true rounded corners on a UITableView? - ios

I say true because while one can do tableView.layer.cornerRadius = 5.0, that method isn't 100%.
It works great when you have enough cells to fill the entire frame of the UITableView, but... if you don't have enough cells to fill it entirely, then you're in a rut because the cells won't be rounded.
I assume the best solution requires rounding the corners of the 1st cell (indexPath.row == 0) and the last cell (indexPath.row == data.count - 1)... but the problematic piece of this is that I need only the top 2 corners of the top cell rounded and the bottom two corners of the bottom cell rounded.
I've thought about using the UIBezierPath/CALayers method, but I don't know how costly it is and further, my cells all have custom heights, so I don't think I can accurately give my cell bounds that the UIBezierPath/CALayers method requires.
How would I achieve this?

The best way to achieve your need is to apply rounded corner to top-left and top-right to first cell and bottom-left and bottom-right to last cell.
Using following code you can apply rounded corner to specific corner of any view.
- (void)applyRoundCornersToView:(UIView *)view withCorners:(UIRectCorner)corners withRadius:(CGFloat)radius {
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius, radius)];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = view.bounds;
maskLayer.path = maskPath.CGPath;
view.layer.mask = maskLayer;
}
You can use above function to apply rounded corner to desired corners.
To apply top corners rounded
[self applyRoundCornersToView:cell withCorners:UIRectCornerTopRight|UIRectCornerTopLeft withRadius:5.0];
To apply bottom corners rounded
[self applyRoundCornersToView:cell withCorners:UIRectCornerBottomRight|UIRectCornerBottomLeft withRadius:5.0];

Related

Collectionview grid with rounded corners at each corner of the grid

I am trying to implement a simple grid of small rectangular cells separated by a grey line. Also, the four corners of my collection view should have rounded corners.
I found that I can't just set the cornerRadius on the UICollectionView layer as that puts the whole collectionview in a 'box' and it looks weird whilst scrolling etc. It looks like I have to round the corner of the 4 cells at each corners.
I ran into the challenges of
Setting the rounded corner on the 4 corner cells WHILST
Setting the actual borders in between the cells
I would be grateful for some pointers. I managed to do it but using graphics for the top, bottom, left and right borders as well as to simulate the rounded edges. And this works for me as my grid has fixed values so I could calculate and work out for each cell what their position was in the grid.
Thanks!
You can set the border of the cells by doing something like
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [...]
if (indexPath.row == 0 && indexPath.section == 0) { // top left
[self roundView:cell.view onCorner:UIRectCornerTopLeft radius:yourRadius];
} else [...]
}
I suggest you to use a function similar to the next one for rounding the corner of the cells
- (void)roundView:(UIView *)view onCorner:(UIRectCorner)rectCorner radius:(float)radius {
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:rectCorner cornerRadii:CGSizeMake(radius, radius)];
CAShapeLayer *maskLayer = [CAShapeLayer new];
maskLayer.frame = view.bounds;
maskLayer.path = maskPath.CGPath;
[view.layer setMask:maskLayer];
}
To set the border between the cells you should create a custom UICollectionViewFlowLayout and set up the frames of all your cells with the method
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect

Rounding edge on UITextField

I have 3 UITextFields with border style none. I want to add borders in code. The effect I want to achieve is to have rounded top corners on first UITextField and to have rounded bottom corners on third text field. Code I am using for rounding edges is here Round top corners of a UIView and add border
But i get this - no right edge and corners are not rounded:
Note: I've set all constraints, that is not a problem. If i use UITextBorderStyleLine right edge is not rounded again.
Please help.
if you want to simplest way to do like on a screen look here>>>
Grey view with clip subviews mode on, and 3 labels/textfields inside, and 2 black view with 1 pixel height
in code..
self.viewCorner.layer.cornerRadius = 6;
self.viewCorner.layer.borderWidth = 1;
self.viewCorner.layer.borderColor = [UIColor blackColor].CGColor;
After you set constraints to grey view and 2 views with 1 pixel height like this
Grey view
1 pixel height view
and result on IPad simulator
Thats all, you can do this for 5 minutes
You need to create custom UItextField or method to change the top and bottom corner to oval shape. Here is a below sample code to top corner similarly you need to do it for bottom left and right corner.
CGRect rect = myTextField.bounds;
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect
byRoundingCorners:UIRectCornerTopLeft |UIRectCornerTopRight
cornerRadii:CGSizeMake(6.0, 6.0)];
CAShapeLayer *layers = [CAShapeLayer layer];
layers.frame = rect;
layers.path = path.CGPath;
myTextField.layer.mask = layers;

How to prevent from clipping the subviews when I set the cornerRadius of a UIView?

I am trying to set the cornerRadius of a subclass view of UIButton, the round corner shows in a right way, but when I try to add a subView(the flower icon) on it, the subview seems to be clipped like the picture on the right side below, this is not what I expected. I try to make the correct appearance like the picture shows on the left side, the icon not be clipped. The code I use:
button.layer.cornerRadius = button.frame.width / 2;
button.layer.masksToBounds = Yes;
Hope someone can help me to understand how to prevent from clipping.
Thanks!
You shouldn't add the overlay as a subview then. Subviews will be clipped if you set clipsToBounds to YES.
Instead add it as a sibling, like so:
- container view
- image view (clips)
- overlay view
If you are making the button rounded using your above mentioned code then your button will definitely get chopped from the corners so if you only want to chop it from 3 corners then do this:
#import <QuartzCore/CoreAnimation.h>
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:button.bounds
byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight | UIRectCornerBottomLeft
cornerRadii:CGSizeMake(7.0, 7.0)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = button.bounds;
maskLayer.path = maskPath.CGPath;
button.layer.mask = maskLayer;

Creating a view with rounding 2 corners [duplicate]

I did a bit of research, and I see, there is no easy way to
make only top right and top left corners of the UIView round, right?
ps. This code makes all 4 corners round which is smth. I don't want.
#import <QuartzCore/QuartzCore.h>
self.layer.cornerRadius = 5;
self.layer.masksToBounds = YES;
You can do it with this snippet:
// Set top right & left corners
[self setMaskTo:yourView byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight];
EDIT
Sorry, I forgot this
- (void)setMaskTo:(UIView*)view byRoundingCorners:(UIRectCorner)corners
{
UIBezierPath *rounded = [UIBezierPath bezierPathWithRoundedRect:view.bounds
byRoundingCorners:corners
cornerRadii:CGSizeMake(8.0, 8.0)];
CAShapeLayer *shape = [[CAShapeLayer alloc] init];
[shape setPath:rounded.CGPath];
view.layer.mask = shape;
}
PS: as I said in the comment, if you use things like this when displaying UITableViewCell cells, I've found that it's always a better choice to use background images because this kind of drawing stuff always affects performance.
I tried extensions for the UIView once and it did not work for me because it have caused problems when drawing a cell
I got a better and easier solution now in 2 steps that worked perfectly good :)
1) One line of code (Swift 2.0) - it wounds all 4 corners of a view:
YourView.layer.cornerRadius = 10
2) and one addition in storyboard you add 1 view with regular corners where you need no round corners and adjust constraints as you need :
note that small regular corner View should be behind the main view. This is how it looks in storyboard
Here you can see constraints needed for the small view

Custom Button frame doesn't look as good as Round Rect UIButton

I'm trying to draw a custom button frame as follows:
UIBezierPath *stroke = [UIBezierPath bezierPathWithRoundedRect:self.bounds
cornerRadius:RECT_CORNECR_RADIUS];
[stroke stroke];
But for some reason the corner curves look thinker than the sides. If you look at the UIButton's default frame it's very uniform. A is a UIButton, B is a custom button.
Any ideas how I can make it more like the UIButton.
You are stroking the bounds of your button. This will draw your line centred over the edge the view, so half of the thickness of the line is outside the bounds and is not drawn. This is why it is full thickness in the corners. Use CGRectInset on your bounds rectangle (inset by half the thickness of your line) and stroke THAT rect.
The problem you have is probably due to antialiasing. You can try to change the antialiasing settings of CoreGraphics before drawing your beizerPath.
An easier solution is to use the CALayer of your button and its cornerRadius property. It would be easier to draw a rounded corner
If self is your custom button:
self.layer.cornerRadius = RECT_CORNER_RADIUS;
self.layer.borderWidth = 1.0f;
self.layer.borderColor = [UIColor blackColor].CGColor;
Of course don't forget to import the QuartzCore framework and import its header for this to work (#import )

Resources