UIView background color not redrawn when frame cha

2019-08-22 07:27发布

问题:

I have a custom UITableViewCell with an UIView in the background, and a UITextView on top.

The UIView is used to set the background color to white, with rounded edges to reveal the cell's contentView.backgroundColor (red) in the corners.

The UITextView height expands correctly when the user enters text.

The UIView (highlighted in the screenshot) has constraints on all 4 sides to grow together with the UITableViewCell. This works correctly (see screenshot, I also checked the frame height).

The problem is that the white UIView.backgroundColor is not expanded, so the "expanded" part is transparent, letting the red contentView.backgroundColor show.

I have tried to call setNeedsLayout on the UIView and/or the UITableViewCell in UITextViewDelegate textViewDidChange, but this did not solve the issue.

Also, setting the background colors in tableView:cellForRowAtIndexPath: or tableView:willDisplayCell:forRowAtIndexPath does not make a difference.

This seems to be similar to this SO post.

How can I have the UIView backgroundColor draw on the whole updated, expanded frame, and not just the original frame?

Update 2018-06-20:

Here is what I'm doing to get the rounded corners (from this SO post)

// from http://stackoverflow.com/questions/4847163/round-two-corners-in-uiview/14485362
- (void)setMaskTo:(id)sender byRoundingCorners:(UIRectCorner)corners withCornerRadii:(CGSize)radii {
    // UIButton requires this
    [sender layer].cornerRadius = 0.0;

    UIBezierPath *shapePath = [UIBezierPath bezierPathWithRoundedRect:[sender bounds]
                                                    byRoundingCorners:corners
                                                          cornerRadii:radii];

    CAShapeLayer *newCornerLayer = [CAShapeLayer layer];
    newCornerLayer.frame = [sender bounds];
    newCornerLayer.path = shapePath.CGPath;
    [sender layer].mask = newCornerLayer;
}   

Then, in tableView:cellForRowAtIndexPath: I call it with

[self setMaskTo:textInputCell.bgColorView byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight) withCornerRadii:CORNER_RADII]; 

回答1:

As mentioned in comments, if you're targeting iOS 11+ you can use CACornerMask (layer.maskedCorners) which allows you to specify specific corners to be rounded.

If you need to support iOS 10 or earlier, you can put your UIBezierPath code in layoutSubviews() - that way, you can update its frame anytime the view's frame changes.