美文网首页iOS~ 贝塞尔曲线:UIBezierPath和CAShapeLayer
ios~ 贝塞尔曲线、折线图📈(UIBezierPath)、CA

ios~ 贝塞尔曲线、折线图📈(UIBezierPath)、CA

作者: 阳光下的叶子呵 | 来源:发表于2022-02-20 02:39 被阅读0次

    雨点🌧、雪花❄️、等:
    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
    
    

    相关文章

      网友评论

        本文标题:ios~ 贝塞尔曲线、折线图📈(UIBezierPath)、CA

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