美文网首页
UIBezierPath绘制带三角的弹窗背景

UIBezierPath绘制带三角的弹窗背景

作者: 清水_yuxin | 来源:发表于2021-03-01 17:08 被阅读0次
image.png
- (void)test {
    YXPopBackgroundView *bgView = [[YXPopBackgroundView alloc] init];
    bgView.center = CGPointMake(200, 200);
    bgView.isTriAngelTop = NO;
    bgView.radius = 20;
    [self.view addSubview:bgView];

    YXPopBackgroundView *bgView2 = [[YXPopBackgroundView alloc] init];
    bgView2.center = CGPointMake(200, 300);
    bgView2.contentSize = CGSizeMake(200, 100);
    bgView2.bgColor = [UIColor redColor];
    bgView2.radius = 5;
    [self.view addSubview:bgView2];
}

1、头文件

@interface YXPopBackgroundView : UIView
/// 内容视图。方便外界直接添加内容,计算frame
@property(nonatomic, strong, readonly) UIView *contentView;
/// 内容大小
@property(nonatomic, assign) CGSize contentSize;
/// 三角高度
@property(nonatomic, assign) CGFloat triAngelHeight;
/// 三角宽度
@property(nonatomic, assign) CGFloat triAngelWidth;
/// 三角距离右边距离
@property(nonatomic, assign) CGFloat triAngelRight;
/// 圆角
@property(nonatomic, assign) CGFloat radius;
/// 背景色
@property(nonatomic, strong) UIColor *bgColor;
/// 三角是否在上。
@property(nonatomic, assign) BOOL isTriAngelTop;

@end

2、实现

#import "YXPopBackgroundView.h"
@interface YXPopBackgroundView()
@property(nonatomic, strong) CAShapeLayer *popLayer;
@property(nonatomic, strong) UIView *contentView;
@end
@implementation YXPopBackgroundView
- (void)setRadius:(CGFloat)radius {
    _radius = radius;
    self.contentView.layer.cornerRadius = radius;
}
- (void)setBgColor:(UIColor *)bgColor {
    _bgColor = bgColor;
    self.popLayer.fillColor = bgColor.CGColor;
}
- (void)setContentSize:(CGSize)contentSize {
    _contentSize = contentSize;
    self.bounds = CGRectMake(0, 0, contentSize.width, contentSize.height+_triAngelHeight);
}
- (instancetype)init {
    self = [super init];
    if (self) {
        self.triAngelHeight = 8.0;
        self.triAngelWidth = 15.0;
        self.triAngelRight = 40.0;
        self.bgColor = [UIColor grayColor];
        self.radius = 15.0;
        self.isTriAngelTop = YES;
        self.contentSize = CGSizeMake(200, 50);
        self.backgroundColor = [UIColor clearColor];

        [self.layer insertSublayer:self.popLayer atIndex:0];
        self.bounds = CGRectMake(0, 0, self.contentSize.width, self.contentSize.height+_triAngelHeight);
        [self addSubview:self.contentView];
        self.contentView.layer.cornerRadius = self.radius;
        self.popLayer.fillColor = self.bgColor.CGColor;
    }
    return self;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    [self updateLayerFrame];

    if (self.isTriAngelTop) {
        self.contentView.frame = CGRectMake(0, _triAngelHeight, _contentSize.width, _contentSize.height);
    }else {
        self.contentView.frame = CGRectMake(0, 0, _contentSize.width, _contentSize.height);
    }
}
- (void)updateLayerFrame {
    
    if (self.isTriAngelTop) {
        self.popLayer.path = [[self getTriAngelTopPath] CGPath];
    }else {
        self.popLayer.path = [[self getTriAngelBottomPath] CGPath];
    }

}
/// 三角在下
- (UIBezierPath *)getTriAngelBottomPath {
    CGSize size = self.bounds.size;
    CGPoint p0 = CGPointMake(size.width-_triAngelRight-_triAngelWidth/2, size.height);
    CGPoint p1 = CGPointMake(p0.x-_triAngelWidth/2, p0.y-_triAngelHeight);
    CGPoint p2 = CGPointMake(_radius, p1.y);
    CGPoint p2_c = CGPointMake(p2.x, p2.y-_radius);
    CGPoint p3 = CGPointMake(0, _radius);
    CGPoint p3_c = CGPointMake(_radius, _radius);
    CGPoint p4 = CGPointMake(size.width-_radius, 0);
    CGPoint p4_c = CGPointMake(p4.x, _radius);
    CGPoint p5 = CGPointMake(size.width, size.height-_triAngelHeight-_radius);
    CGPoint p5_c = CGPointMake(p5.x-_radius, p5.y);
    CGPoint p6 = CGPointMake(size.width-_triAngelRight, size.height-_triAngelHeight);
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:p0];
    [path addLineToPoint:p1];
    [path addLineToPoint:p2];
    [path addArcWithCenter:p2_c radius:_radius startAngle:M_PI_2 endAngle:M_PI_2*2 clockwise:YES];
    [path addLineToPoint:p3];
    [path addArcWithCenter:p3_c radius:_radius startAngle:M_PI_2*2 endAngle:M_PI_2*3 clockwise:YES];
    [path addLineToPoint:p4];
    [path addArcWithCenter:p4_c radius:_radius startAngle:M_PI_2*3 endAngle:0 clockwise:YES];
    [path addLineToPoint:p5];
    [path addArcWithCenter:p5_c radius:_radius startAngle:0 endAngle:M_PI_2 clockwise:YES];
    [path addLineToPoint:p6];
    return path;
}
/// 三角在上
- (UIBezierPath *)getTriAngelTopPath {
    CGSize size = self.bounds.size;
    CGPoint p0 = CGPointMake(size.width-_triAngelRight-_triAngelWidth/2, 0);
    CGPoint p1 = CGPointMake(p0.x+_triAngelWidth/2, p0.y+_triAngelHeight);
    CGPoint p2 = CGPointMake(p1.x+_triAngelRight-_radius, p1.y);
    CGPoint p2_c = CGPointMake(p2.x, p2.y+_radius);
    CGPoint p3 = CGPointMake(size.width, size.height-_radius);
    CGPoint p3_c = CGPointMake(p2.x, p3.y);
    CGPoint p4 = CGPointMake(_triAngelHeight, size.height);
    CGPoint p4_c = CGPointMake(_radius, size.height-_radius);
    CGPoint p5 = CGPointMake(0, _triAngelHeight+_radius);
    CGPoint p5_c = CGPointMake(_radius, p5.y);
    CGPoint p6 = CGPointMake(p0.x-_triAngelWidth/2, _triAngelHeight);
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:p0];
    [path addLineToPoint:p1];
    [path addLineToPoint:p2];
    [path addArcWithCenter:p2_c radius:_radius startAngle:M_PI_2*3 endAngle:0 clockwise:YES];
    [path addLineToPoint:p3];
    [path addArcWithCenter:p3_c radius:_radius startAngle:0 endAngle:M_PI_2 clockwise:YES];
    [path addLineToPoint:p4];
    [path addArcWithCenter:p4_c radius:_radius startAngle:M_PI_2 endAngle:M_PI_2*2 clockwise:YES];
    [path addLineToPoint:p5];
    [path addArcWithCenter:p5_c radius:_radius startAngle:M_PI_2*2 endAngle:M_PI_2*3 clockwise:YES];
    [path addLineToPoint:p6];
    return path;
}
- (CAShapeLayer *)popLayer {
    if (!_popLayer) {
        _popLayer = [[CAShapeLayer alloc] init];
    }
    return _popLayer;
}
- (UIView *)contentView {
    if (!_contentView) {
        _contentView = [UIView new];
        _contentView.backgroundColor = [UIColor clearColor];
        _contentView.layer.masksToBounds = YES;
    }
    return _contentView;
}
@end

相关文章

网友评论

      本文标题:UIBezierPath绘制带三角的弹窗背景

      本文链接:https://www.haomeiwen.com/subject/onvafltx.html