zoukankan      html  css  js  c++  java
  • iOS 谁说程序猿不懂浪漫之 爱心

    近来无事,想想IT该怎样才能彰显浪漫情怀,不能口头上说说而已,最关键的是要有可视化的东西展示出来才行~

    废话不多说,直接上Demo

    HeartView.h

     1 //
     2 //  HeartView.h
     3 //  DrawHeart
     4 //
     5 //  Created by WQL on 16/3/1.
     6 //  Copyright © 2016年 WQL. All rights reserved.
     7 //
     8 
     9 #import <UIKit/UIKit.h>
    10 
    11 @interface HeartView : UIView
    12 /**
    13  *  比率
    14  */
    15 @property (nonatomic,assign) CGFloat rate;
    16 /**
    17  *  填充的颜色
    18  */
    19 @property (nonatomic,strong) UIColor *fillColor;
    20 /**
    21  *  线条的颜色
    22  */
    23 @property (nonatomic,strong) UIColor *strokeColor;
    24 /**
    25  *  线条的宽度
    26  */
    27 @property (nonatomic,assign) CGFloat lineWidth;
    28 @end

    HeartView.m文件:

      1 //
      2 //  HeartView.m
      3 //  DrawHeart
      4 //
      5 //  Created by WQL on 16/3/1.
      6 //  Copyright © 2016年 WQL. All rights reserved.
      7 //
      8 
      9 #import "HeartView.h"
     10 //间距
     11 NSInteger const spaceWidth = 5;
     12 //波浪的振幅
     13 NSInteger const waveAmplitude = 5;
     14 @interface HeartView ()
     15 {
     16     CGFloat t;
     17 }
     18 @end
     19 
     20 @implementation HeartView
     21 
     22 - (instancetype)initWithFrame:(CGRect)frame
     23 {
     24     self = [super initWithFrame:frame];
     25     if (self) {
     26         [self loadTimer];
     27     }
     28     return self;
     29 }
     30 
     31 - (void)drawRect:(CGRect)rect
     32 {
     33     [super drawRect:rect];
     34     
     35     //上面的两个半圆 半径为整个frame的四分之一
     36     CGFloat radius = MIN((self.frame.size.width-spaceWidth*2)/4, (self.frame.size.height-spaceWidth*2)/4);
     37     
     38     //左侧圆心 位于左侧边距+半径宽度
     39     CGPoint leftCenter = CGPointMake(spaceWidth+radius, spaceWidth+radius);
     40     //右侧圆心  位于左侧圆心的右侧 距离为两倍半径
     41     CGPoint rightCenter = CGPointMake(spaceWidth+radius*3, spaceWidth+radius);
     42     
     43     //左侧半圆
     44     UIBezierPath *heartLine = [UIBezierPath bezierPathWithArcCenter:leftCenter radius:radius startAngle:M_PI endAngle:0 clockwise:YES];
     45 
     46     //右侧半圆
     47     [heartLine addArcWithCenter:rightCenter radius:radius startAngle:M_PI endAngle:0 clockwise:YES];
     48     
     49     //曲线连接到新的底部顶点  为了弧线的效果,控制点,坐标x为总宽度减spaceWidth,刚好可以相切,平滑过度 y可以根据需要进行调整,y越大,所画出来的线越接近内切圆弧
     50     [heartLine addQuadCurveToPoint:CGPointMake((self.frame.size.width/2), self.frame.size.height-spaceWidth*2) controlPoint:CGPointMake(self.frame.size.width-spaceWidth, self.frame.size.height*0.6)];
     51     
     52     //用曲线 底部的顶点连接到左侧半圆的左起点 为了弧线的效果,控制点,坐标x为spaceWidth,刚好可以相切,平滑过度。y可以根据需要进行调整,y越大,所画出来的线越接近内切圆弧(效果是越胖)
     53     [heartLine addQuadCurveToPoint:CGPointMake(spaceWidth, spaceWidth+radius) controlPoint:CGPointMake(spaceWidth, self.frame.size.height*0.6)];
     54     
     55     //线条处理
     56     [heartLine setLineCapStyle:kCGLineCapRound];
     57     //线宽
     58     [self setHeartLineWidthWithPath:heartLine];
     59     //线条的颜色
     60     [self setHeartStrokeColor];
     61     
     62     //根据坐标点连线
     63     [heartLine stroke];
     64     //clipToBounds 切掉多余的部分
     65     [heartLine addClip];
     66     
     67     
     68     //初始化波浪的构成
     69     UIBezierPath *waves = [UIBezierPath bezierPath];
     70     
     71     //首先 把起始点设置为左侧 x坐标为spaceWidth 心形从下往上填充,y坐标需要满足一定的函数关系式,当rate为0时,位置为总高度-2倍的留白距离(spaceWidth)+波浪的振幅;当rate为1时,位置为留白距离(spaceWidth)-振幅。由这两个状态构建函数表达式,即可得到如下表达式
     72     CGPoint startPoint = CGPointMake(spaceWidth, (self.frame.size.height-3*spaceWidth+waveAmplitude*2)*(1-self.rate)+spaceWidth-waveAmplitude);
     73     [waves moveToPoint:startPoint];
     74     
     75     //关键的地方来了 波浪线怎么画?
     76     //首先,x坐标是从左往右连续的  y坐标是起始的高度加上一定的波动 这里选择了cos函数。5是波动的幅度大小,50控制的是波峰的间距,t是为了让其动起来,随时间发生波动
     77     for (int i = 0; i<self.frame.size.width-spaceWidth*2+self.lineWidth*2; i++) {
     78         //x是要考虑线宽的 不然的话,会导致填充的宽度不够 y就是在某个值附近波动
     79         CGPoint middlePoint = CGPointMake(spaceWidth+i-self.lineWidth, startPoint.y+waveAmplitude*cos(M_PI/50*i+t));
     80         
     81         [waves addLineToPoint:middlePoint];
     82     }
     83     
     84     //画波浪线的右端 到底部的垂直线
     85     [waves addLineToPoint:CGPointMake(self.frame.size.width-spaceWidth*2, self.frame.size.height-spaceWidth*2)];
     86     //画右侧底部的点 到达左侧底部的点之间的横线
     87     [waves addLineToPoint:CGPointMake(spaceWidth, self.frame.size.height-spaceWidth*2)];
     88     //设置填充颜色
     89     [self setHeartFillColor];
     90     //填充
     91     [waves fill];
     92     
     93 }
     94 //设置线条宽度 默认为1
     95 - (void)setHeartLineWidthWithPath:(UIBezierPath*)path
     96 {
     97     CGFloat lineW;
     98     if (self.lineWidth) {
     99         lineW = self.lineWidth;
    100     }else{
    101         lineW = 1;
    102     }
    103     
    104     [path setLineWidth:lineW];
    105 }
    106 
    107 //设置线条颜色
    108 - (void)setHeartStrokeColor
    109 {
    110     UIColor *strokColor;
    111     if (self.strokeColor) {
    112         strokColor = self.strokeColor;
    113     }else{
    114         strokColor = [UIColor blackColor];
    115     }
    116     
    117     [strokColor set];
    118 }
    119 //设置填充的颜色
    120 - (void)setHeartFillColor
    121 {
    122     UIColor *fillColor;
    123     if (self.fillColor) {
    124         fillColor = self.fillColor;
    125     }else{
    126         fillColor = [UIColor orangeColor];
    127     }
    128     
    129     [fillColor set];
    130 
    131 }
    132 
    133 //为了实现动态的效果,加一个Timer
    134 - (void)loadTimer
    135 {
    136     NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
    137     [timer fire];
    138 }
    139 //t 是一个影响波浪线的参数,每次修改之,再画,则每次的都不一样,则有动态的效果
    140 - (void)timerAction
    141 {
    142     t += M_PI/50;
    143     
    144     if (t == M_PI) {
    145         t = 0;
    146     }
    147     //修改了t之后 要调用draw方法
    148     [self setNeedsDisplay];
    149 }
    150 
    151 @end

    一些关键点,我已经注释啦~

    下面就是看看怎么使用这个视图了:

    ViewController.m中:

     1 //
     2 //  ViewController.m
     3 //  DrawHeart
     4 //
     5 //  Created by WQL on 16/3/1.
     6 //  Copyright © 2016年 WQL. All rights reserved.
     7 //
     8 
     9 #import "ViewController.h"
    10 #import "HeartView.h"
    11 
    12 NSInteger const heartWidth = 200;
    13 NSInteger const heartHeight = 200;
    14 
    15 @interface ViewController ()
    16 {
    17     HeartView *heartView;
    18 }
    19 @end
    20 
    21 @implementation ViewController
    22 
    23 - (void)viewDidLoad {
    24     [super viewDidLoad];
    25     heartView = [[HeartView alloc]initWithFrame:CGRectMake((self.view.frame.size.width-heartWidth)/2, (self.view.frame.size.height-heartHeight)/2, heartWidth, heartHeight)];
    26 
    27     heartView.rate = 0.5;
    28     heartView.lineWidth = 1;
    29     heartView.strokeColor = [UIColor blackColor];
    30     heartView.fillColor = [UIColor redColor];
    31     heartView.backgroundColor = [UIColor clearColor];
    32     [self.view addSubview:heartView];
    33     
    34     [self loadSlider];
    35 }
    36 
    37 - (void)loadSlider
    38 {
    39     UISlider *valueSlider = [[UISlider alloc]initWithFrame:CGRectMake((self.view.frame.size.width-300)/2, self.view.frame.size.height-150, 300, 50)];
    40     valueSlider.minimumValue = 0.0;
    41     valueSlider.maximumValue = 1.0;
    42     valueSlider.value = 0.5;
    43     [valueSlider addTarget:self action:@selector(valueChangedAction:) forControlEvents:UIControlEventValueChanged];
    44     [self.view addSubview:valueSlider];
    45 }
    46 
    47 - (void)valueChangedAction:(UISlider*)slider
    48 {
    49     heartView.rate = slider.value;
    50 }
    51 
    52 
    53 - (void)didReceiveMemoryWarning {
    54     [super didReceiveMemoryWarning];
    55     // Dispose of any resources that can be recreated.
    56 }
    57 
    58 @end

    这里我添加了一个slider,为了实现随意设置爱心填充的rate。

    哈,下面就是看看效果了:

    (请原谅我不会弄gif图,它的实际效果是可以不断晃动的~)

    如果有感兴趣的小伙伴可以去下载看一下,地址是:https://github.com/Coolll/DrawHeart.git

    欢迎各位园友提出意见和建议,如有不足,请多多指教,拜谢~

    这里是博客园的下载地址:Download

  • 相关阅读:
    获取腾讯soso地图坐标代码
    PHP获取服务器的mac地址类
    关于PHPExcel导出Excel时身份证,数字会导出为科学计数的处理方法
    PhpExcel笔记,phpExcel中文帮助手册
    微信开发之——Php批量生成带参数的二维码
    [转载]数据管理——数据血缘关系概述
    HDFS学习总结
    CDH5.7Hadoop集群搭建(离线版)
    QlikSense系列(1)——整体介绍
    Python学习小计
  • 原文地址:https://www.cnblogs.com/520myp1314/p/5234364.html
Copyright © 2011-2022 走看看