CAShapeLayer with UIRectCornerBottomLeft / Right makes my view fade out

OK. I did google search, stack search, Wenderlich search (is that anything else?). I've tried everything here on overflow and nothing seems to work.

I need a CALayer expert.

I have a tableView which I am showing as a dropdown from the top of my application. It shows thin and dandy until I try to go around the bottom left / right corners. Every try I tried resulted in my table disappearing completely. The methods still work and I am getting workarounds for the up / down methods. However, the table just disappears.

Code with tableView:

- (void)setupTopMenu {
    CGFloat screenWidth = [[UIScreen mainScreen] bounds].size.width;

    self.topMenuTable = [[UITableView alloc] initWithFrame:CGRectMake((screenWidth / 2) - ((screenWidth - topMenuSideBuffer) / 2), self.view.frame.origin.y + topBuffer, (screenWidth - topMenuSideBuffer), 0) style:UITableViewStylePlain];
    self.topMenuTable.backgroundColor = DARK_BLUE_NAVBAR_COLOR;
    self.topMenuTable.dataSource = self;
    self.topMenuTable.delegate = self;
    self.topMenuTable.scrollEnabled = YES;
    self.topMenuTable.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
    self.topMenuTable.separatorColor = [UIColor blackColor];
    self.topMenuTable.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
    self.topMenuTable.layer.borderColor = [UIColor blackColor].CGColor;
    self.topMenuTable.layer.borderWidth = 0.4f;

    UIBezierPath *maskPath;
    maskPath = [UIBezierPath bezierPathWithRoundedRect:self.topMenuTable.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.topMenuTable.layer.mask = maskLayer;

    [self.view addSubview:self.topMenuTable];
}

      

Code with just a view (I thought it might have something to do with the table view, but it behaves the same when I use a regular UIView)

- (void)setupTopMenu {
    CGFloat screenWidth = [[UIScreen mainScreen] bounds].size.width;

    self.topMenuView = [[UIView alloc] initWithFrame:CGRectMake((screenWidth / 2) - ((screenWidth - topMenuSideBuffer) / 2), self.view.frame.origin.y + topBuffer, (screenWidth - topMenuSideBuffer), 0)];
    self.topMenuView.backgroundColor = [UIColor redColor];
    self.topMenuView.layer.borderColor = [UIColor blackColor].CGColor;
    self.topMenuView.layer.borderWidth = 0.4f;

    UIBezierPath *maskPath;
    maskPath = [UIBezierPath bezierPathWithRoundedRect:self.topMenuView.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.topMenuView.layer.mask = maskLayer;

    [self.view addSubview:self.topMenuView];
}

      

The code I'm using to show the view (s):

- (void)showTopMenu {

    if (!isTopMenuDown) {
        [UIView animateWithDuration:0.45 animations:^ {
            //self.topMenuTable.frame = CGRectMake((self.screenWidth / 2) - (self.topMenuWidth / 2), self.view.bounds.origin.y + topBuffer, self.topMenuWidth, self.topMenuHeight);
            self.topMenuView.frame = CGRectMake((self.screenWidth / 2) - (self.topMenuWidth / 2), self.view.bounds.origin.y + topBuffer, self.topMenuWidth, self.topMenuHeight);
        } completion:^(BOOL finished) {

        }];
    } else {
        [UIView animateWithDuration:0.35 animations:^ {
            // self.topMenuTable.frame = CGRectMake((self.screenWidth / 2) - (self.topMenuWidth /2), self.view.bounds.origin.y + topBuffer, self.topMenuWidth, 0);
            self.topMenuView.frame = CGRectMake((self.screenWidth / 2) - (self.topMenuWidth /2), self.view.bounds.origin.y + topBuffer, self.topMenuWidth, 0);
        } completion:^ (BOOL finished) {

        }];
    }

    isTopMenuDown =! isTopMenuDown;
}

      

NOTE. I also tried to add a mask to the layer, for example in Round multiple corners of UIView and around border of view layers

The same result.

If I rip out the Layer code, the views render fine, but with the layer code, they disappear.

Is there something in the way I am showing the view that I cannot see it disappearing?

Thanks for the help.

+3


source to share


1 answer


I thought it might have something to do with the TableView, but it behaves the same when I use a regular UIView

Exactly, because it has nothing to do with the table view. This is because you don't understand what a mask is.

A mask layer blocks parts of its layer based on the opacity of the mask layer. You haven't done anything to select the opaque parts of the mask from the transparent parts. Your whole mask is transparent. Thus, the whole layer is meaning, the whole view is blocked (invisible).

I think you are describing something like this (I exaggerated the rounding of corners, just for show):



enter image description here

It's a rectangle with a mask on it. The mask consists of a filled rounded rectangle. Thus, the interior of the path is opaque and appears; the appearance is transparent and does not appear.

Just FYI, this is how I created the mask and added it (I used an image and contents

, but you can certainly use a shape layer if you like):

UIView* viewToMask = self.view.subviews[0];
UIGraphicsBeginImageContextWithOptions(viewToMask.bounds.size, NO, 0);
UIBezierPath* round = [UIBezierPath bezierPathWithRoundedRect:viewToMask.bounds byRoundingCorners: (UIRectCornerBottomLeft | UIRectCornerBottomRight) cornerRadii:CGSizeMake(50,50)];
[round fill];
UIImage* result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CALayer* mask = [CALayer new];
mask.frame = viewToMask.bounds;
mask.contents = (id)result.CGImage;
viewToMask.layer.mask = mask;

      

+1


source







All Articles