最近实现一个气泡的效果,使用CGPathRef自定义不规则的气泡样式,但是由于使用了UIView的clipsToBounds属性
导致气泡显示不一样,如果设置了clipsToBounds
会导致设置的shadow不能正常显示,带入如下:
UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 140, 45)];
[self.view addSubview:contentView];
contentView.clipsToBounds = YES;
ShadowView *shadowView = [[ShadowView alloc] initWithFrame:contentView.bounds];
[contentView addSubview:shadowView];
设置clipsToBounds=YES
显示效果如下:
这是由于设置contentView的clipsToBound=YES
, 那contentView上的subview在绘制shadow的时候,由于shadow已经超出frame,所以shadow
绘制出来不是预期的效果,superview的clipsToBound
会影响subview的阴影绘制,个人觉得是一个比较大的坑。
设置clipsToBounds=NO
显示正常:
其中ShadowView
的设置气泡样式的代码如下:
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_bubbleHeight = 5;
CGPathRef bubblePath = [self bubblePath];
self.opaque = FALSE;
self.backgroundColor = [UIColor clearColor];
self.layer.shadowPath = bubblePath;
self.layer.shadowColor = [UIColor greenColor].CGColor;
self.layer.shadowRadius = 5;
self.layer.shadowOpacity = 1.0;
self.layer.shadowOffset = CGSizeMake(0, 0);
CGPathRelease(bubblePath);
}
return self;
}
- (CGPathRef)bubblePath {
CGFloat radius = CGRectGetHeight(self.bounds) / 2.0 - 5;
CGFloat bubbleHeight = _bubbleHeight;
CGFloat bubbleWidth = 8;
CGFloat drawWidth = CGRectGetWidth(self.bounds);
CGFloat drawHeight = CGRectGetHeight(self.bounds) - bubbleHeight;
//left corner
CGMutablePathRef bubblePath = CGPathCreateMutable();
CGPathMoveToPoint(bubblePath, NULL, radius, 0);
CGPathAddArcToPoint(bubblePath, NULL, 0, 0, 0, radius, radius);
//left-bottom corner
CGPathAddLineToPoint(bubblePath, NULL, 0, drawHeight - radius);
CGPathAddArcToPoint(bubblePath, NULL, 0, drawHeight, radius, drawHeight, radius);
//bottom down-arrow
CGPathAddLineToPoint(bubblePath, NULL, (drawWidth - bubbleWidth) / 2, drawHeight);
CGPathAddLineToPoint(bubblePath, NULL, drawWidth / 2, drawHeight + bubbleHeight);
CGPathAddLineToPoint(bubblePath, NULL, (drawWidth + bubbleWidth) / 2, drawHeight);
//right-bottom corner
CGPathAddLineToPoint(bubblePath, NULL, drawWidth - radius, drawHeight);
CGPathAddArcToPoint(bubblePath, NULL, drawWidth, drawHeight, drawWidth, drawHeight - radius, radius);
//right-top corner
CGPathAddLineToPoint(bubblePath, NULL, drawWidth, radius);
CGPathAddArcToPoint(bubblePath, NULL, drawWidth, 0, drawWidth - radius, 0, radius);
//move brush to start point
CGPathAddLineToPoint(bubblePath, NULL, radius, 0);
return bubblePath;
}