Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIBezierPath on UILabel in UITableViewCell has screwed up sizes

I have this method for rounding corners inside of a subclass of UITableViewCell but whenever it is called it produces weird behavior that results in labels that are not correctly sized the first time around and then are correctly sized but with horrible borders the second time it is show:

-(UIView *)roundCornersOnView:(UIView *)view onTopLeft:(BOOL)tl topRight:(BOOL)tr bottomLeft:(BOOL)bl bottomRight:(BOOL)br radius:(float)radius WithBorder:(BOOL)showBorder
{

    if (tl || tr || bl || br) {
        UIRectCorner corner = 0; //holds the corner
        //Determine which corner(s) should be changed
        if (tl) {
            corner = corner | UIRectCornerTopLeft;
        }
        if (tr) {
            corner = corner | UIRectCornerTopRight;
        }
        if (bl) {
            corner = corner | UIRectCornerBottomLeft;
        }
        if (br) {
            corner = corner | UIRectCornerBottomRight;
        }

        UIView *roundedView = view;
        UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:roundedView.bounds byRoundingCorners:corner cornerRadii:CGSizeMake(radius, radius)];
        CAShapeLayer *maskLayer = [CAShapeLayer layer];
        maskLayer.frame = roundedView.bounds;
        maskLayer.path = maskPath.CGPath;
        roundedView.layer.mask = maskLayer;
        if(showBorder){
        CAShapeLayer *borderLayer = [[CAShapeLayer alloc] init];
            borderLayer.frame = roundedView.bounds;
            borderLayer.path  = maskPath.CGPath;
            borderLayer.lineWidth   = 4.0f;
            borderLayer.strokeColor = [UIColor whiteColor].CGColor;
            borderLayer.fillColor   = [UIColor clearColor].CGColor;
            [roundedView.layer addSublayer:borderLayer];
        }
        return roundedView;
    } else {
        return view;
    }

}

this is called in -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath as such below:

TimeOfDayCell * c = [tableView dequeueReusableCellWithIdentifier:@"weekdaySelectorOn"];

            c.day.text = [self.weekdays objectAtIndex:[self weekdayNormalizedIndexForIndexPath:indexPath]];
            c.day = (UILabel *)[c roundCornersOnView:c.day onTopLeft:YES topRight:YES bottomLeft:NO bottomRight:NO radius:12.0 WithBorder:NO];
            c.time1 = (UILabel *)[c roundCornersOnView:c.time1 onTopLeft:NO topRight:NO bottomLeft:YES bottomRight:YES radius:12.0 WithBorder:YES];
            c.time2 = (UILabel *)[c roundCornersOnView:c.time2 onTopLeft:NO topRight:NO bottomLeft:YES bottomRight:YES radius:12.0 WithBorder:YES];
            c.time3 = (UILabel *)[c roundCornersOnView:c.time3 onTopLeft:NO topRight:NO bottomLeft:YES bottomRight:YES radius:12.0 WithBorder:YES];

This yields the following weird output, the first picture being the first time the cell is shown, the second being when the cell is shown a second time:

On the first showing of this cell

On the second showing of the cell

like image 332
Erik Avatar asked Aug 25 '15 16:08

Erik


1 Answers

So, it turns out not only did I need to put this in -(void)layoutSubviews I also needed to explicitly tell the contentView to layoutIfNeeded but even this was not enough, I had to also add setNeedsLayout

Full solution in UITableViewCell:

-(void)layoutSubviews
{
    [super layoutSubviews];
    [self.contentView setNeedsLayout];
    [self.contentView layoutIfNeeded];
    self.day = (UILabel *)[self roundCornersOnView:self.day onTopLeft:YES topRight:YES bottomLeft:NO bottomRight:NO radius:12.0 WithBorder:NO];
    self.time1 = (UILabel *)[self roundCornersOnView:self.time1 onTopLeft:NO topRight:NO bottomLeft:YES bottomRight:YES radius:12.0 WithBorder:YES];
    self.time2 = (UILabel *)[self roundCornersOnView:self.time2 onTopLeft:NO topRight:NO bottomLeft:YES bottomRight:YES radius:12.0 WithBorder:YES];
    self.time3 = (UILabel *)[self roundCornersOnView:self.time3 onTopLeft:NO topRight:NO bottomLeft:YES bottomRight:YES radius:12.0 WithBorder:YES];
}
like image 87
Erik Avatar answered Sep 28 '22 07:09

Erik