ios~ 贝塞尔曲线、折线图📈(UIBezierPath)、CAShapeLayer、渐变色:CAGradientLayer、雨点🌧等:CAEmitterLayer和CAEmitterCell

雨点🌧、雪花❄️、等:
1、【基于CAEmitterLayer的下雨、下雪、火焰、烟花粒子动画效果demo】
2、【iOS 粒子效果实现:CAEmitterLayer + CAEmitterCell】
3、【iOS CAEmitterLayer CAEmitterCell初探(粒子效果初探,属性以及简单示例)】
4、iOS:CAEmitterLayer粒子效果【轻点或拖动来改变发射源的位置】

图片:

降水曲线图.jpeg

代码:

#import "GWCW_Club_ActualWeatherRainCell.h"
#import "GWActualGameChartToolLine.h" // 虚线

@interface GWCW_Club_ActualWeatherRainCell ()
 
@property (nonatomic, strong) UIView    *topView;
@property (nonatomic, strong) UIView    *bottomView;

@property (nonatomic, strong) UIView    *backView;
/** 雨水提示*/
@property (nonatomic, strong) UILabel   *rainTipsL;
@property (nonatomic, strong) UIView    *rainBackView;

@property (nonatomic, strong) CAShapeLayer  *rainBackLayer; // 添加一个父layer

@property (nonatomic) UILabel   *nowTimeL;
@property (nonatomic) UILabel   *hour1TimeL;
@property (nonatomic) UILabel   *hour2TimeL;

// 降雨数组

@end

@implementation GWCW_Club_ActualWeatherRainCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.selectionStyle = UITableViewCellSelectionStyleNone;
        self.backgroundColor = ColorGlobalBalck;
        [self setupUI];
    }
    return self;
}

- (void)prepareForReuse {
    [super prepareForReuse];
//    self.sunriseImg.image = nil;
//    self.sunriseTimeL.text = nil;
//    self.sunsetImg.image = nil;
//    self.sunsetTimeL.text = nil;
//    [self.sunLayer removeFromSuperlayer]; // 防止重用 在cell中时
//    self.sunImg.image = nil;
    self.rainTipsL.text = nil;
    self.nowTimeL.text = nil;
    self.hour1TimeL.text = nil;
    self.hour2TimeL.text = nil;
    [self.rainBackLayer removeFromSuperlayer];
}

- (void)setWeatherModel:(GWActualMatchWeatherModel *)weatherModel {
    _weatherModel = weatherModel;
    
    self.nowTimeL.text = @"现在";
    self.hour1TimeL.text = @"1小时后";
    self.hour2TimeL.text = @"2小时后";
    
    self.backView.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/375*20, [UIScreen mainScreen].bounds.size.width/375*22, [UIScreen mainScreen].bounds.size.width/375*(375-40), self.frame.size.height - [UIScreen mainScreen].bounds.size.width/375*(22+15));
    
    self.rainTipsL.text = [NSString stringWithFormat:@"%@", _weatherModel.precipitationDesc];
    // 多行文本(高度)
    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
    [style setLineBreakMode:NSLineBreakByCharWrapping];
    style.lineSpacing = 4;
    // 设置行间距:
    NSMutableAttributedString *attriString = [[NSMutableAttributedString alloc] initWithString:self.rainTipsL.text];
    [attriString addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, [self.rainTipsL.text length])];
    self.rainTipsL.attributedText = attriString;
    
    // 降雨数组
    NSMutableArray *rainArray = [NSMutableArray arrayWithCapacity:0];
    if (_weatherModel.precipitation.count == 120) { // 两小时的降水量,一分钟一个数,下面每十分钟一个数量
        
        
        // 降水量( 0 ~ 1)
        for (int i = 0; i < 13; i++) { // 取出其中的前12个十分钟的数据(从当前开始,0~11)
            
            if (i == 0) {
                NSNumber *rainNumber = _weatherModel.precipitation[0];
                [rainArray addObject:rainNumber];
            } else {
                NSNumber *rainNumber = _weatherModel.precipitation[i*10-1];
                [rainArray addObject:rainNumber];
            }
        }
        
        /** 1、创建父layer */
        _rainBackLayer = [[CAShapeLayer alloc] init];
        _rainBackLayer.strokeColor = [UIColor clearColor].CGColor;
        
        UIBezierPath *bezierPath = [UIBezierPath
                                        bezierPathWithRoundedRect:CGRectMake(0, 0, self.rainBackView.frame.size.width, self.rainBackView.frame.size.height)
                                        byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight
                                        cornerRadii:CGSizeMake([UIScreen mainScreen].bounds.size.width/375*0, [UIScreen mainScreen].bounds.size.width/375*0)];

        _rainBackLayer.lineWidth = [UIScreen mainScreen].bounds.size.width/375*0.01;
        // 颜色
        _rainBackLayer.strokeColor = [UIColor clearColor].CGColor;
        // 背景填充色
        _rainBackLayer.fillColor = [UIColor clearColor].CGColor;
        _rainBackLayer.path = [bezierPath CGPath];
        [self.rainBackView.layer addSublayer:self.rainBackLayer];
        
        
        /**
         将CAGradientLayer渐变色,添加到折线图上,实现原理:
         
         1、首先,将 CAShapeLayer 添加 父 rainBackView 上,(rainBackView.layer上面 添加各种layer);

         2、将CAGradientLayer渐变色,添加到 rainBackLayer上;

         3、再,画出两个 以折线图📈的折线,为边界的两个 layer,折线图📈上、下各一个,下边layer 填充色设置透明,上边layer 设置填充色为父视图的背景色(用以遮挡上半部分的渐变色);
         
         4、最后,将那三条虚线添加上去,就完成了。

         5、添加雨点、雪花 等效果。
         */
        /** 渐变色条,在上面添加虚线CAShapeLayer */
        CAGradientLayer *gradient = [CAGradientLayer layer];
        // 写成固定的大小(和self.backView的frame一样)
        gradient.frame = CGRectMake(0, 0, self.rainBackView.frame.size.width, self.rainBackView.frame.size.height);
        gradient.colors = [NSArray arrayWithObjects:
                               (id)[UIColor colorWithRed:88/255.0 green:159/255.0 blue:232/255.0 alpha:0.9].CGColor,
                               (id)[UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1].CGColor,
                                nil];
        gradient.startPoint = CGPointMake(0.5, 0);
        gradient.endPoint = CGPointMake(0.5, 1);
        gradient.masksToBounds = YES;
        gradient.cornerRadius = [UIScreen mainScreen].bounds.size.width/375*0;
        [self.rainBackLayer addSublayer:gradient];
        
        
        /** 降水 贝塞尔曲线 (下边的曲线图范围)*/
        UIBezierPath *rainPath = [UIBezierPath bezierPath];
        // 第一个点,起始点 和 终点 连线起来。
        [rainPath moveToPoint:CGPointMake(-2, [UIScreen mainScreen].bounds.size.width/375*51)];
        
        if (rainArray.count >= 13) {
            // 上边的 第一个点
            NSNumber *topOneNumber = rainArray[0];
            CGFloat topOnePoint = [topOneNumber floatValue];
            [rainPath addLineToPoint:CGPointMake(-2, [UIScreen mainScreen].bounds.size.width/375*(50-(50*topOnePoint)))];
            
            // 两个相邻 端点 的位置间隔:
            CGFloat intervalWidth = [UIScreen mainScreen].bounds.size.width/375*(375-40-24)/12;
            
            
//            NSNumber *endNumber1 = rainArray[3];
//            CGFloat endPoint1 = [endNumber1 floatValue];
            // 1
            [rainPath addCurveToPoint:CGPointMake(intervalWidth*3, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[3] floatValue])))
                        controlPoint1:CGPointMake(intervalWidth*1, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[1] floatValue])))
                        controlPoint2:CGPointMake(intervalWidth*2, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[2] floatValue])))];
            // 2
            [rainPath addCurveToPoint:CGPointMake(intervalWidth*6, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[6] floatValue])))
                        controlPoint1:CGPointMake(intervalWidth*4, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[4] floatValue])))
                        controlPoint2:CGPointMake(intervalWidth*5, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[5] floatValue])))];
            // 3
            [rainPath addCurveToPoint:CGPointMake(intervalWidth*9, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[9] floatValue])))
                        controlPoint1:CGPointMake(intervalWidth*7, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[7] floatValue])))
                        controlPoint2:CGPointMake(intervalWidth*8, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[8] floatValue])))];
            // 4
            [rainPath addCurveToPoint:CGPointMake(intervalWidth*12+2, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[12] floatValue])))
                        controlPoint1:CGPointMake(intervalWidth*10, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[10] floatValue])))
                        controlPoint2:CGPointMake(intervalWidth*11, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[11] floatValue])))];
        }
        
        // 终点
        [rainPath addLineToPoint:CGPointMake([UIScreen mainScreen].bounds.size.width/375*(375-40-24)+2, [UIScreen mainScreen].bounds.size.width/375*51)];
        
        CAShapeLayer *rainLayer = [[CAShapeLayer alloc] init];
        // 线宽
        rainLayer.lineWidth = [UIScreen mainScreen].bounds.size.width/375*2;
        // 线条的颜色
        rainLayer.strokeColor = RGBA(135, 190, 241, 1).CGColor;
        // 背景填充色
        rainLayer.fillColor = [UIColor clearColor].CGColor;
        // 起始点和终点,连接起来。(可以先添加”起始点“和”终点“的y轴为0,加上这句之后,范围内的填充颜色。)
        [rainPath closePath];
        // 将UIBezierPath类转换成CGPath,类似于UIColor的CGColor
        rainLayer.path = [rainPath CGPath];
        [self.rainBackLayer addSublayer:rainLayer];
        
        
        /** 降水 贝塞尔曲线 (上边的曲线图范围:设置白色部分,(实现渐变色效果))*/
        UIBezierPath *topPath = [UIBezierPath bezierPath];
        // 第一个点,起始点 和 终点 连线起来。
        [topPath moveToPoint:CGPointMake(-2, -[UIScreen mainScreen].bounds.size.width/375*1)];
        if (rainArray.count >= 13) {
            NSNumber *topNumber = rainArray[0];
            CGFloat topPoint = [topNumber floatValue];
            [topPath addLineToPoint:CGPointMake(-2, [UIScreen mainScreen].bounds.size.width/375*(50-(50*topPoint)))];
            
            // 两个相邻 端点 的位置间隔:
            CGFloat intervalWidth = [UIScreen mainScreen].bounds.size.width/375*(375-40-24)/12;
            
            // 1
            [topPath addCurveToPoint:CGPointMake(intervalWidth*3, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[3] floatValue])))
                        controlPoint1:CGPointMake(intervalWidth*1, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[1] floatValue])))
                        controlPoint2:CGPointMake(intervalWidth*2, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[2] floatValue])))];
            // 2
            [topPath addCurveToPoint:CGPointMake(intervalWidth*6, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[6] floatValue])))
                        controlPoint1:CGPointMake(intervalWidth*4, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[4] floatValue])))
                        controlPoint2:CGPointMake(intervalWidth*5, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[5] floatValue])))];
            // 3
            [topPath addCurveToPoint:CGPointMake(intervalWidth*9, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[9] floatValue])))
                        controlPoint1:CGPointMake(intervalWidth*7, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[7] floatValue])))
                        controlPoint2:CGPointMake(intervalWidth*8, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[8] floatValue])))];
            // 4
            [topPath addCurveToPoint:CGPointMake(intervalWidth*12+2, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[12] floatValue])))
                        controlPoint1:CGPointMake(intervalWidth*10, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[10] floatValue])))
                        controlPoint2:CGPointMake(intervalWidth*11, [UIScreen mainScreen].bounds.size.width/375*(50-(50*[rainArray[11] floatValue])))];
            
        }
        
        // 终点
        [topPath addLineToPoint:CGPointMake([UIScreen mainScreen].bounds.size.width/375*(375-40-24)+2, -[UIScreen mainScreen].bounds.size.width/375*1)];
        
        CAShapeLayer *topLayer = [[CAShapeLayer alloc] init];
        // 线宽
        topLayer.lineWidth = [UIScreen mainScreen].bounds.size.width/375*2;
        // 线条的颜色
        topLayer.strokeColor = RGBA(135, 190, 241, 1).CGColor;
        // 背景填充色
        topLayer.fillColor = [UIColor whiteColor].CGColor;
        // 起始点和终点,连接起来。(可以先添加”起始点“和”终点“的y轴为0,加上这句之后,范围内的填充颜色。)
        [topPath closePath];
        // 将UIBezierPath类转换成CGPath,类似于UIColor的CGColor
        topLayer.path = [topPath CGPath];
        [self.rainBackLayer addSublayer:topLayer];
        
    }
    
    if ([_weatherModel.rain containsString:@"雨"] && ![_weatherModel.rain containsString:@"雪"]) {
        // 雨🌧
//        [self rainWeather_icon];
        [self rainAndSnowWeather_icon];
        
    } else if (![_weatherModel.rain containsString:@"雨"] && [_weatherModel.rain containsString:@"雪"]) {
        // 雪❄️
        [self snowWeather_icon];
    } else if ([_weatherModel.rain containsString:@"雨"] && [_weatherModel.rain containsString:@"雪"]) {
        // 雨夹雪🌧❄️
        [self rainAndSnowWeather_icon];
    }
    
    
    
//    if (_weatherModel.hourlyData.count > 0) {
//        for (int i = 0; i<_weatherModel.hourlyData.count; i++) {
//            [self.tempArr addObject:@(_weatherModel.hourlyData[i].temp)];
////            [self.rainArr addObject:@(_weatherModel.hourlyData[i].rain)];
//            self.rainArr = [_weatherModel.precipitation mutableCopy];
//        }
//    }

}

#pragma mark -- 实现下雨🌧效果:
- (void)rainWeather_icon {
    /** 粒子发射器:CAEmitterLayer 和 CAEmitterCell  */
    
    
    //    1、设置CAEmitterLayer
    CAEmitterLayer *rainLayer = [CAEmitterLayer layer];
    
    // 2、在背景图上添加粒子图层
//    [self.rainBackLayer addSublayer:rainLayer];
    [self.rainBackView.layer addSublayer:rainLayer];
    
    // 3、发射形状--线性
    rainLayer.emitterShape = kCAEmitterLayerLine;
    //发射模式
    rainLayer.emitterMode = kCAEmitterLayerSurface;
    //
    rainLayer.renderMode = kCAEmitterLayerUnordered;
    //发射形状的大小
    rainLayer.emitterSize = self.rainBackView.frame.size;
    //发射的中心点位置(显示 雨滴的范围 self.rainBackView.frame.size 这个范围网上移动 ”1“)
    rainLayer.emitterPosition = CGPointMake(self.rainBackView.bounds.size.width*0.5, -1);
    // rainLayer.emitterPosition = CGPointMake(self.frame.origin.x, self.frame.origin.y);
    
    // 4、配置cell
    CAEmitterCell *emitterCell = [CAEmitterCell emitterCell];

    // 粒子排放的范围(2 * M_2_PI)整个范围,(1 * M_2_PI)上面emitterPosition-1的范围
    emitterCell.emissionRange  = 2 * M_2_PI;
    
    
    //粒子图片(本地图片的名字)
    emitterCell.contents = (id)[[UIImage imageNamed:@"club_weather_雨点_icon"] CGImage];
    //每秒钟创建的粒子对象,默认是0
    emitterCell.birthRate = 5.f;
    //粒子的生存周期,以s为单位,默认是0
    emitterCell.lifetime = 10.f;
    //粒子发射的速率,默认是1
    emitterCell.speed = 2;
    //粒子的初始平均速度及范围,默认为0
    emitterCell.velocity = 10.0f;
    emitterCell.velocityRange = 10.0f;
    //y方向的加速度矢量,默认是0
    emitterCell.yAcceleration = 6.f;
    //粒子的缩放比例及范围,默认是[1,0]
    emitterCell.scale = 0.5;
    emitterCell.scaleRange = 0.0f;
    
    // 5、添加到图层上
    rainLayer.emitterCells = @[emitterCell];
    
}

#pragma mark -- 实现下雪❄️效果:
- (void)snowWeather_icon {
    
    //    1、设置CAEmitterLayer
    CAEmitterLayer *rainLayer = [CAEmitterLayer layer];
    
    // 2、在背景图上添加粒子图层
    [self.rainBackView.layer addSublayer:rainLayer];
    
    // 3、发射形状--线性
    rainLayer.emitterShape = kCAEmitterLayerLine;
    //发射模式
    rainLayer.emitterMode = kCAEmitterLayerSurface;
    //
    rainLayer.renderMode = kCAEmitterLayerUnordered;
    //发射形状的大小
    rainLayer.emitterSize = self.rainBackView.frame.size;
    //发射的中心点位置(显示雪花 的范围 self.rainBackView.frame.size 这个范围网上移动 ”1“)
    rainLayer.emitterPosition = CGPointMake(self.rainBackView.bounds.size.width*0.5, -1);
    // rainLayer.emitterPosition = CGPointMake(self.frame.origin.x, self.frame.origin.y);
    
    // 4、配置cell
    CAEmitterCell *emitterCell = [CAEmitterCell emitterCell];

    // 粒子排放的范围(2 * M_2_PI)整个范围,(1 * M_2_PI)上面emitterPosition-1的范围
    emitterCell.emissionRange  = 1 * M_2_PI;
    
    //粒子图片(本地图片的名字)
    emitterCell.contents = (id)[[UIImage imageNamed:@"club_weather_雪点_icon"] CGImage];
    //每秒钟创建的粒子对象,默认是0
    emitterCell.birthRate = 5.f;
    //粒子的生存周期,以s为单位,默认是0
    emitterCell.lifetime = 10.f;
    //粒子发射的速率,默认是1
    emitterCell.speed = 2;
    //粒子的初始平均速度及范围,默认为0
    emitterCell.velocity = 10.0f;
    emitterCell.velocityRange = 10.0f;
    //y方向的加速度矢量,默认是0
    emitterCell.yAcceleration = 6.f;
    //粒子的缩放比例及范围,默认是[1,0]
    emitterCell.scale = 0.5;
    emitterCell.scaleRange = 0.0f;
    
    // 5、添加到图层上
    rainLayer.emitterCells = @[emitterCell];
   
}
#pragma mark -- 实现下 雨🌧 + 雪❄️ 效果:
- (void)rainAndSnowWeather_icon {
    
    //    1、设置CAEmitterLayer
    CAEmitterLayer *rainLayer = [CAEmitterLayer layer];
    
    // 2、在背景图上添加粒子图层
    [self.rainBackView.layer addSublayer:rainLayer];
    
    // 3、发射形状--线性
    rainLayer.emitterShape = kCAEmitterLayerLine;
    //发射模式
    rainLayer.emitterMode = kCAEmitterLayerSurface;
    //
    rainLayer.renderMode = kCAEmitterLayerUnordered;
    //发射形状的大小
    rainLayer.emitterSize = self.rainBackView.frame.size;
    //发射的中心点位置(显示雪花 的范围 self.rainBackView.frame.size 这个范围网上移动 ”1“)
    rainLayer.emitterPosition = CGPointMake(self.rainBackView.bounds.size.width*0.5, -1);
    // rainLayer.emitterPosition = CGPointMake(self.frame.origin.x, self.frame.origin.y);
    
    // 4、配置cell
    CAEmitterCell *rainEmitterCell = [CAEmitterCell emitterCell];
    
    // 粒子排放的范围(2 * M_2_PI)整个范围,(1 * M_2_PI)上面emitterPosition-1的范围
    rainEmitterCell.emissionRange  = 2 * M_2_PI;
    
    //粒子图片(本地图片的名字)
    rainEmitterCell.contents = (id)[[UIImage imageNamed:@"club_weather_雨点_icon"] CGImage];
    //每秒钟创建的粒子对象,默认是0
    rainEmitterCell.birthRate = 5.f;
    //粒子的生存周期,以s为单位,默认是0
    rainEmitterCell.lifetime = 10.f;
    //粒子发射的速率,默认是1
    rainEmitterCell.speed = 2;
    //粒子的初始平均速度及范围,默认为0
    rainEmitterCell.velocity = 10.0f;
    rainEmitterCell.velocityRange = 10.0f;
    //y方向的加速度矢量,默认是0
    rainEmitterCell.yAcceleration = 6.f;
    //粒子的缩放比例及范围,默认是[1,0]
    rainEmitterCell.scale = 0.5;
    rainEmitterCell.scaleRange = 0.0f;
    
    CAEmitterCell *snowEmitterCell = [CAEmitterCell emitterCell];
    
    // 粒子排放的范围(2 * M_2_PI)整个范围,(1 * M_2_PI)上面emitterPosition-1的范围
    snowEmitterCell.emissionRange  = 2 * M_2_PI;
    
    //粒子图片(本地图片的名字)
    snowEmitterCell.contents = (id)[[UIImage imageNamed:@"club_weather_雪点_icon"] CGImage];
    //每秒钟创建的粒子对象,默认是0
    snowEmitterCell.birthRate = 4.f;
    //粒子的生存周期,以s为单位,默认是0
    snowEmitterCell.lifetime = 10.f;
    //粒子发射的速率,默认是1
    snowEmitterCell.speed = 2;
    //粒子的初始平均速度及范围,默认为0
    snowEmitterCell.velocity = 10.0f;
    snowEmitterCell.velocityRange = 10.0f;
    //y方向的加速度矢量,默认是0
    snowEmitterCell.yAcceleration = 6.f;
    //粒子的缩放比例及范围,默认是[1,0]
    snowEmitterCell.scale = 0.5;
    snowEmitterCell.scaleRange = 0.0f;
    
    // 5、添加到图层上
    rainLayer.emitterCells = @[rainEmitterCell, snowEmitterCell];
    
}

- (void)setupUI {
    
    _topView = [[UIView alloc] init];
    _topView.backgroundColor = RGBA(248, 249, 250, 1);
    self.topView.layer.masksToBounds = YES;
    self.topView.layer.cornerRadius = [UIScreen mainScreen].bounds.size.width/375*20;
    [self.contentView addSubview:self.topView];
    [self.topView makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.top.equalTo(self);
        make.height.mas_equalTo([UIScreen mainScreen].bounds.size.width/375*60);
    }];
    
    _bottomView = [[UIView alloc] init];
    _bottomView.backgroundColor = RGBA(248, 249, 250, 1);
    [self.contentView addSubview:self.bottomView];
    [self.bottomView makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.bottom.equalTo(self);
        make.top.mas_equalTo([UIScreen mainScreen].bounds.size.width/375*20);
    }];
    
    _backView = [[UIView alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/375*20, [UIScreen mainScreen].bounds.size.width/375*22, [UIScreen mainScreen].bounds.size.width/375*(375-40), self.frame.size.height - [UIScreen mainScreen].bounds.size.width/375*(22+15))];
    _backView.backgroundColor = [UIColor whiteColor];
//    self.backView.layer.masksToBounds = YES;
    self.backView.layer.cornerRadius = [UIScreen mainScreen].bounds.size.width/375*12;
    self.backView.layer.shadowColor = RGBA(0, 0, 0, 0.05).CGColor;
    self.backView.layer.shadowOffset = CGSizeMake(0, 5);
    self.backView.layer.shadowRadius = [UIScreen mainScreen].bounds.size.width/375*6;
    self.backView.layer.shadowOpacity = 1;
    [self.contentView addSubview:self.backView];
//    _backView.backgroundColor = [UIColor redColor];
    
//    [self.backView makeConstraints:^(MASConstraintMaker *make) {
//        make.top.mas_equalTo(self.mas_top).offset([UIScreen mainScreen].bounds.size.width/375*22);
//        make.left.mas_equalTo(self.mas_left).offset([UIScreen mainScreen].bounds.size.width/375*20);
//        make.right.mas_equalTo(self.mas_right).offset(-[UIScreen mainScreen].bounds.size.width/375*20);
//        make.bottom.mas_equalTo(self.mas_bottom).offset(-[UIScreen mainScreen].bounds.size.width/375*15);
//    }];
    
    _rainTipsL = [[UILabel alloc] init];
    _rainTipsL.textColor = RGBA(0, 0, 0, 0.8);
    _rainTipsL.textAlignment = NSTextAlignmentLeft;
    _rainTipsL.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*15 weight:UIFontWeightRegular];
    self.rainTipsL.numberOfLines = 2;
    [self.backView addSubview:self.rainTipsL];
    [self.rainTipsL makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(self.backView.mas_top).offset([UIScreen mainScreen].bounds.size.width/375*12);
        make.left.mas_equalTo(self.backView.mas_left).offset([UIScreen mainScreen].bounds.size.width/375*12);
        make.right.mas_equalTo(self.backView.mas_right).offset(-[UIScreen mainScreen].bounds.size.width/375*12);
        make.height.mas_equalTo([UIScreen mainScreen].bounds.size.width/375*50);
    }];
    
    
    _rainBackView = [[UIView alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/375*12, [UIScreen mainScreen].bounds.size.width/375*75, [UIScreen mainScreen].bounds.size.width/375*(375-40-24), [UIScreen mainScreen].bounds.size.width/375*50)];
    self.rainBackView.backgroundColor = [UIColor clearColor];
    [self.backView addSubview:self.rainBackView];
    self.rainBackView.layer.masksToBounds = YES; // 超出layer边界,就裁减掉,防止子layer越界
    
    [self setupAAChartToolLine];
    
    UIView *lineView = [[UIView alloc] init];
    lineView.backgroundColor = RGBA(216, 216, 216, 1);
    [self.backView addSubview:lineView];
    [lineView makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.equalTo(self.rainBackView);
        make.top.mas_equalTo(self.rainBackView.mas_bottom);
        make.height.mas_equalTo([UIScreen mainScreen].bounds.size.width/375*1);
    }];
    
    
    _nowTimeL = [[UILabel alloc] init];
    _nowTimeL.textColor = RGBA(0, 0, 0, 0.3);
    _nowTimeL.textAlignment = NSTextAlignmentLeft;
    _nowTimeL.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*11 weight:UIFontWeightRegular];
    [self.backView addSubview:self.nowTimeL];
    [self.nowTimeL makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(self.rainBackView.mas_bottom).offset([UIScreen mainScreen].bounds.size.width/375*5);
        make.left.mas_equalTo(self.backView.mas_left).offset([UIScreen mainScreen].bounds.size.width/375*13);
    }];
    
    _hour1TimeL = [[UILabel alloc] init];
    _hour1TimeL.textColor = RGBA(0, 0, 0, 0.3);
    _hour1TimeL.textAlignment = NSTextAlignmentCenter;
    _hour1TimeL.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*11 weight:UIFontWeightRegular];
    [self.backView addSubview:self.hour1TimeL];
    [self.hour1TimeL makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.nowTimeL);
        make.centerX.equalTo(self.rainBackView);
    }];
    
    _nowTimeL = [[UILabel alloc] init];
    _nowTimeL.textColor = RGBA(0, 0, 0, 0.3);
    _nowTimeL.textAlignment = NSTextAlignmentRight;
    _nowTimeL.font = [UIFont systemFontOfSize:[UIScreen mainScreen].bounds.size.width/375*11 weight:UIFontWeightRegular];
    [self.backView addSubview:self.nowTimeL];
    [self.nowTimeL makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.nowTimeL);
        make.right.mas_equalTo(self.backView.mas_right).offset([UIScreen mainScreen].bounds.size.width/375*13);
    }];
    
}

-(void)setupAAChartToolLine{
    GWActualGameChartToolLine *bottomLineView = [[GWActualGameChartToolLine alloc]init];
    bottomLineView.backgroundColor = RGBA(2, 91, 172, 0.2);
    [self.backView addSubview:bottomLineView];
    [bottomLineView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.rainBackView.mas_top);
        make.height.offset(APP_transverse_Scale(1));
        make.left.right.equalTo(self.rainBackView);
    }];
    
    for (int i =0 ; i<2; i++) {
        GWActualGameChartToolLine *toolLine = [[GWActualGameChartToolLine alloc]init];
        toolLine.backgroundColor = RGBA(2, 91, 172, 0.2);
        [self.backView addSubview:toolLine];
        [toolLine mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(self.rainBackView.mas_top).offset(APP_transverse_Scale(50/3) *i +APP_transverse_Scale(50/3));
            make.height.offset(APP_transverse_Scale(1));
            make.left.right.equalTo(self.rainBackView);
        }];
    }
}


- (void)awakeFromNib {
    [super awakeFromNib];
    // Initialization code
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

@end
虚线.h
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface GWActualGameChartToolLine : UIView

@end

NS_ASSUME_NONNULL_END
虚线.m
#import "GWActualGameChartToolLine.h"

@implementation GWActualGameChartToolLine
- (void)drawRect:(CGRect)rect{
    [self drawDottedLine];
}
-(void)drawDottedLine{
    
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];

    [shapeLayer setBounds:self.bounds];


    [shapeLayer setPosition:CGPointMake(CGRectGetWidth(self.frame) / 2, CGRectGetHeight(self.frame))];



    [shapeLayer setFillColor:[UIColor clearColor].CGColor];
    //  设置虚线颜色为blackColor
    [shapeLayer setStrokeColor:[[UIColor whiteColor] CGColor]];
    //  设置虚线宽度
        [shapeLayer setLineWidth:CGRectGetHeight(self.frame)];
  
    [shapeLayer setLineJoin:kCALineJoinRound];
    //  设置线宽,线间距
    [shapeLayer setLineDashPattern:[NSArray arrayWithObjects:[NSNumber numberWithInt:1], [NSNumber numberWithInt:1], nil]];
    //  设置路径
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, 0, 0);

    CGPathAddLineToPoint(path, NULL,CGRectGetWidth(self.frame), 0);
    [shapeLayer setPath:path];
    CGPathRelease(path);
    //  把绘制好的虚线添加上来
    [self.layer addSublayer:shapeLayer];
}

@end

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

推荐阅读更多精彩内容