3

Example project: http://cl.ly/1l1x1A0J3o2X

I have a child view controller that has a UITableView in it, and this view controller sits on top of another view controller. I want to give the bottom of it rounded corners (but only the bottom).

In my UITableView subclass I have this code to round the bottom corners.

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        UIBezierPath *maskPath;
        maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight) cornerRadii:CGSizeMake(5.0, 5.0)];

        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
        maskLayer.frame = self.bounds;
        maskLayer.path = maskPath.CGPath;
        self.layer.mask = maskLayer;

        self.backgroundColor = [UIColor colorWithRed:0.169 green:0.169 blue:0.169 alpha:1];
    }
    return self;
}

Which does indeed round them, but as soon as I scroll the table view it moves it up further and decreases in height (seemingly at least).

However, if I simply use self.layer.cornerRadius = 5.0 it completely operates fine.

Does anyone know why this behaviour might be the case?

  • What do you mean "moves it up further?" What is "it"? The cell? The mask? Are you using auto-layout? IF so a constraint might be resizing your cell's layer. I don't remember if the system resizes a layer's mask layer automatically or not. – Duncan C Dec 14 '13 at 19:15
  • Sorry. Visibly it looks like the tableview is shifted upwards as I scroll, instead of its scrollview. Here's an example project where I mask the containing view of the table view in its view controller per the request of the answer: http://cl.ly/1l1x1A0J3o2X but if you simply move that to the table view's `initWithCoder` it creates the effect we're talking about. –  Dec 14 '13 at 21:01

2 Answers2

0

UIScrollView, and thus the subclass UITableView, actually renders its content by changing the bounds of what it's rendering. My guess is that adding a mask to the UITableView's layer is actually adding the mask to the content within the view, not the container like you might imagine.

Why 'self.layer.cornerRadius = 5.0' works, and your approach doesn't, I am not sure.

An approach that would work better was already given for a similar request, so I'll direct you over to:

Adding Rounded Corners to only top of UITableView?

Basically, the recommendation was to put the UITableView into a container and add the mask to the container. I believe that would work just fine.

Community
  • 1
  • 1
Acey
  • 8,048
  • 4
  • 30
  • 46
  • Here's an example project: http://cl.ly/1l1x1A0J3o2X I tried in the `viewDidLoad` of that view controller adding the mask to `self.view.layer` but it still doesn't work. –  Dec 14 '13 at 20:58
  • You could also set the mask to have the size of the table view's *frame*, then, in `scrollViewDidScroll:`, adjust the position of the mask so that it stays pinned to the visible portion of the table view. – Austin Dec 18 '13 at 19:58
0

This might not be an exact answer. But I am gonna give you an workaround.

Look at this question and answer.

How to get an UITableView working with CAShapeLayer mask? https://stackoverflow.com/a/11538923/1083859

This will give you a clue what I tried.

As in that question explained, adding tableView mask will not going to work for you, because it will move with your tableView as you explained. So I tried adding a another superview for the tableView in your DropDownViewController and add a outlet for it.

enter image description here

Then I changed your code inside the viewDidLoad in DropDownViewController to add the mask for current superview of tableView like below.

UIBezierPath *maskPath;
maskPath = [UIBezierPath bezierPathWithRoundedRect:self.tableSuperView.bounds byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight) cornerRadii:CGSizeMake(5.0, 5.0)];

CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.view.bounds;
maskLayer.path = maskPath.CGPath;
self.tableSuperView.layer.mask = maskLayer;

and that's it. It works. And I found an unwanted behavior when scroll the tableView to the end. It happens because of tableView bounce animation. If you remove that animation, then you are good to go.

Glad to know your opinion and result.

Community
  • 1
  • 1
Dinesh Raja
  • 8,501
  • 5
  • 42
  • 81