需求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更新了,不要那么明显的分割线,需要用阴影了,方案废弃
阴影的实现效果:
阴影的实现代码:
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:弧线进度条
效果如图:
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;
效果:
其他阴影相关补充:
shadowOpacity
的取值范围在0.0-1之间,如果是1,会显示一个稍微的黑影在视图上
shadowColor
阴影颜色 类型是CGColorRef
shadowOffset
控制着阴影的方向和距离:类型是CGSize,宽度控制这阴影横向的位移,高度控制着纵向的位移, 默认值是 {0, -3},意即阴影相对于Y轴有3个点的向上位移。
shadowRadius
属性控制着阴影的模糊度,值越大越模糊
shadowPath
属性,
实时计算阴影也是一个非常消耗资源的,尤其是图层有多个子图层,每个图层还有一个有透明效果的寄宿图的时候
如果你事先知道你的阴影形状会是什么样子的,你可以通过指定一个shadowPath来提高性能,shadowpath属性是CGPathRef类型,用来指定任意的一个矢量图形
如果是标准的矩形阴影或者圆形阴影,就用CGPathRef来实现
如果是其他类型的阴影,就用UIBezierPath类会更合适