UIBezierPath繪制帶三角的彈窗背景

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
/// 內(nèi)容視圖蒿辙。方便外界直接添加內(nèi)容思灌,計算frame
@property(nonatomic, strong, readonly) UIView *contentView;
/// 內(nèi)容大小
@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、實現(xiàn)

#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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市檀葛,隨后出現(xiàn)的幾起案子空扎,更是在濱河造成了極大的恐慌,老刑警劉巖润讥,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件转锈,死亡現(xiàn)場離奇詭異,居然都是意外死亡楚殿,警方通過查閱死者的電腦和手機撮慨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人砌溺,你說我怎么就攤上這事影涉。” “怎么了规伐?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵蟹倾,是天一觀的道長。 經(jīng)常有香客問我猖闪,道長鲜棠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任培慌,我火速辦了婚禮岔留,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘检柬。我一直安慰自己,他們只是感情好竖配,可當(dāng)我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布何址。 她就那樣靜靜地躺著,像睡著了一般进胯。 火紅的嫁衣襯著肌膚如雪用爪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天胁镐,我揣著相機與錄音偎血,去河邊找鬼。 笑死盯漂,一個胖子當(dāng)著我的面吹牛颇玷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播就缆,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼帖渠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了竭宰?” 一聲冷哼從身側(cè)響起空郊,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎切揭,沒想到半個月后狞甚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡廓旬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年哼审,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡棺蛛,死狀恐怖怔蚌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情旁赊,我是刑警寧澤桦踊,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站终畅,受9級特大地震影響籍胯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜离福,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一杖狼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧妖爷,春花似錦蝶涩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至次舌,卻和暖如春熄攘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背彼念。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工挪圾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人逐沙。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓哲思,卻偏偏與公主長得像,于是被迫代替她去往敵國和親酱吝。 傳聞我的和親對象是個殘疾皇子也殖,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容