iOS圆角加边框实现和弧线进度条实现笔记

需求1:有顶部两个圆角,外加一条很明显的分割线

顶部有边框,边框带圆角

效果

1

添加边框和layer的代码实现:

-(UIView *)topView {
    if (_topView == nil) {
        _topView = [[UIView alloc] initWithFrame:CGRectMake(0, Screen_Height - 234 - 50 - SafeAreaBottomHeight - 15, Screen_Width, 30)];
        _topView.backgroundColor = [UIColor whiteColor];
        UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:_topView.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(15,15)];
        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
        maskLayer.frame = _topView.bounds;
        maskLayer.path = maskPath.CGPath;
        _topView.layer.mask = maskLayer;
        
        
        UIBezierPath *bezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(15, 15) radius:15 startAngle: - M_PI_2 endAngle: - M_PI  clockwise:NO];
        bezierPath.lineWidth = 1;
        bezierPath.lineCapStyle = kCGLineCapRound;
        [bezierPath stroke];
        CAShapeLayer * bezierLineLayer  = [CAShapeLayer layer];
        bezierLineLayer.path = bezierPath.CGPath;
        bezierLineLayer.strokeColor = [UIColor grayColor].CGColor;
        bezierLineLayer.fillColor = [[UIColor clearColor] CGColor];
        bezierLineLayer.lineCap = kCALineCapRound;
        bezierLineLayer.lineJoin = kCALineJoinRound;
        [_topView.layer addSublayer:bezierLineLayer];
        
        CALayer * layer = [CALayer layer];
        layer.borderWidth = 0.5;
        layer.borderColor = [UIColor grayColor].CGColor;
        layer.frame = CGRectMake(15, 0, Screen_Width - 30, 0.5);
        [_topView.layer addSublayer:layer];
        
        UIBezierPath *bezierPath3 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(Screen_Width - 15, 15) radius:15 startAngle:0.0 endAngle: - M_PI_2  clockwise:NO];
        bezierPath3.lineWidth = 1;
        bezierPath3.lineCapStyle = kCGLineCapRound;
        [bezierPath3 stroke];
        CAShapeLayer * bezierLineLayer3  = [CAShapeLayer layer];
        bezierLineLayer3.path = bezierPath3.CGPath;
        bezierLineLayer3.strokeColor = [UIColor grayColor].CGColor;
        bezierLineLayer3.fillColor = [[UIColor clearColor] CGColor];
        bezierLineLayer3.lineCap = kCALineCapRound;
        bezierLineLayer3.lineJoin = kCALineJoinRound;
        [_topView.layer addSublayer:bezierLineLayer3];
        
        
    }
    return _topView;
}

后来UI更新了,不要那么明显的分割线,需要用阴影了,方案废弃

阴影的实现效果:


3

阴影的实现代码:
shadowRadius值设置可以让阴影有模糊和虚化效果
shadowOffset值是阴影的方向-4是指往顶部打阴影

        _topView.backgroundColor = [UIColor whiteColor];
        _topView.layer.shadowColor = [UIColor grayColor].CGColor;
        _topView.layer.shadowOpacity = 0.1f;
        _topView.layer.shadowRadius = 3;
        _topView.layer.shadowOffset = CGSizeMake(0, - 4);
        _topView.layer.cornerRadius = 15;
        CALayer *maskLayer = [CALayer layer];
        maskLayer.frame = _topView.layer.bounds;
        maskLayer.masksToBounds = YES;
        [_topView.layer addSublayer:maskLayer];

需求2:弧线进度条

效果如图:


2.png

layer画弧注意三点
1:x坐标轴是0.0旋转一圈是2π
2.layer方案的线宽是通过 bezierLineLayer.lineWidth = 2.0f;来设置,而不是path.linwidth来设置
3.直接在需要的地方画弧线是没有上下文环境的,虽然效果能画成功,但是会打印一堆令人难受的日志
为了应对第3条所描述的情况:
直接创建一个YZDrawView继承UIView

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface YZDrawView : UIView
- (instancetype)initWithFrame:(CGRect)frame startDegree:(CGFloat)start endDegree:(CGFloat)end linWidth:(CGFloat)lineWidth stockColor:(UIColor *)stockColor;
@end

NS_ASSUME_NONNULL_END

在为了应对第3条描述的情况,需要在drawRect方法中画弧
lineWidth + 0.5是为了应对有锯齿的情况,
clockwise 为YES表示顺时针画弧

#import "YZDrawView.h"

@interface YZDrawView()
@property(nonatomic,assign)CGFloat start;
@property(nonatomic,assign)CGFloat end;
@property(nonatomic,strong)UIColor * stockColor;
@property(nonatomic,assign)CGFloat lineWidth;
@end

@implementation YZDrawView


- (instancetype)initWithFrame:(CGRect)frame startDegree:(CGFloat)start endDegree:(CGFloat)end linWidth:(CGFloat)lineWidth stockColor:(UIColor *)stockColor;
{
    self = [super initWithFrame:frame];
    
    if (self) {
        self.backgroundColor = [UIColor clearColor];
        _start = start;
        _end = end;
        _lineWidth = lineWidth;
        _stockColor = stockColor;
    }
    return self;
}
- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    
    UIBezierPath *bezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(rect.size.width / 2, rect.size.height / 2) radius:(rect.size.width / 2 - _lineWidth) startAngle: _start  endAngle:  _end  clockwise:YES];
    bezierPath.lineWidth = _lineWidth;
    bezierPath.lineCapStyle = kCGLineCapRound;
    [bezierPath stroke];
    CAShapeLayer * bezierLineLayer  = [CAShapeLayer layer];
    bezierLineLayer.path = bezierPath.CGPath;
    bezierLineLayer.strokeColor = self.stockColor.CGColor;
    bezierLineLayer.fillColor = [UIColor clearColor].CGColor;
    bezierLineLayer.lineCap = kCALineCapRound;
    bezierLineLayer.lineWidth = _lineWidth + 0.5;
    bezierLineLayer.lineJoin = kCALineJoinRound;
    bezierLineLayer.contentsScale = [[UIScreen mainScreen] scale];
    [self.layer addSublayer:bezierLineLayer];
}
@end

使用

胜率的值是从0 到 1,对应的弧度值是从 - π / 2 到 3 π / 2;
二元一次方程求得end值为y = 2 * π * x - π / 2;

画两个view,其中一个cicleBgView是背景view,弧线宽度为2,弧线是从0-2π的一整个圆.弧线填充颜色是灰色

-(YZDrawView *)cicleBgView {
    if (_cicleBgView == nil) {
        _cicleBgView = [[YZDrawView alloc] initWithFrame:CGRectMake(0, 0, 40, 40) startDegree:0.0 endDegree: 2 * M_PI linWidth:2.0 stockColor:UIColorHex(#019866)];
    }
    return _cicleBgView;
}

-(void)func {
    [self.rightInnerView addSubView:self. cicleBgView];
}

第二个persentRoundView是服务端返回数据之后,比如胜率是80%,服务端返回rightTimes值为@"80",那么在原有的view上再覆盖一个弧线即可实现效果,弧线填充颜色是黄色

    CGFloat value = [rightTimes doubleValue] / 100.0;
    CGFloat end = 2 * M_PI * value - M_PI_2;
    CGFloat start = - M_PI_2;
    
    self.persentRoundView = [[YZDrawView alloc] initWithFrame:CGRectMake(0, 0, 40, 40) startDegree:start endDegree:end linWidth:2.0 stockColor:[UIColor yellowColor]];
    [self.rightInnerView addSubview:self.persentRoundView];

需求3:Label上加斜线

label的常规代码

-(UILabel *)originLab {
    if (_originLab == nil) {
        _originLab = [[UILabel alloc] init];
        _originLab.text = @"原价¥5000";
        _originLab.textAlignment = NSTextAlignmentLeft;
        _originLab.font = [UIFont boldSystemFontOfSize:12];
        _originLab.textColor = UIColorHex(#A4CFFF);
    }
    return _originLab;
}

        [self.originLab mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(self.moneyPayLab.mas_right).offset(7.5);
            make.top.equalTo(_bgCardView.mas_top).offset(52);
            make.height.equalTo(@14);
            make.width.greaterThanOrEqualTo(@50);
        }];

根据起点和终点给lablel上画一条斜线

        [self.originLab layoutIfNeeded];
        
          CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
          shapeLayer.lineWidth = 1.0;
          shapeLayer.strokeColor = [UIColor whiteColor].CGColor;
          shapeLayer.fillColor = [UIColor clearColor].CGColor;
          UIBezierPath *path = [[UIBezierPath alloc] init];
          [path moveToPoint:CGPointMake(0, 1)];//斜线的起点
        [path addLineToPoint:CGPointMake(self.originLab.frame.size.width, 12)];//斜线的终点
          shapeLayer.path = path.CGPath;
        [self.originLab.layer addSublayer:shapeLayer];
        _shapLineLayer = shapeLayer;

效果:

4.jpeg

其他阴影相关补充:
shadowOpacity 的取值范围在0.0-1之间,如果是1,会显示一个稍微的黑影在视图上
shadowColor 阴影颜色 类型是CGColorRef
shadowOffset 控制着阴影的方向和距离:类型是CGSize,宽度控制这阴影横向的位移,高度控制着纵向的位移, 默认值是 {0, -3},意即阴影相对于Y轴有3个点的向上位移。
shadowRadius 属性控制着阴影的模糊度,值越大越模糊

shadowPath属性,
实时计算阴影也是一个非常消耗资源的,尤其是图层有多个子图层,每个图层还有一个有透明效果的寄宿图的时候
如果你事先知道你的阴影形状会是什么样子的,你可以通过指定一个shadowPath来提高性能,shadowpath属性是CGPathRef类型,用来指定任意的一个矢量图形
如果是标准的矩形阴影或者圆形阴影,就用CGPathRef来实现
如果是其他类型的阴影,就用UIBezierPath类会更合适

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容