iOS绘制专属于程序猿的浪漫爱心绘制专属于程序猿的浪漫爱心
谁说程序猿不懂浪漫,这篇文章主要介绍了iOS绘制专属于程序猿的浪漫爱心,感兴趣的小伙伴们可以参考一下
近来无事,想想IT该怎样才能彰显浪漫情怀,不能口头上说说而已,最关键的是要有可视化的东西展示出来才行~
废话不多说,直接上Demo
HeartView.h
//
// HeartView.h
// DrawHeart
//
// Created by WQL on 16/3/1.
// Copyright © 2016年 WQL. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface HeartView : UIView
/**
* 比率
*/
@property (nonatomic,assign) CGFloat rate;
/**
* 填充的颜色
*/
@property (nonatomic,strong) UIColor *fillColor;
/**
* 线条的颜色
*/
@property (nonatomic,strong) UIColor *strokeColor;
/**
* 线条的宽度
*/
@property (nonatomic,assign) CGFloat lineWidth;
@end
HeartView.m文件:
//
// HeartView.m
// DrawHeart
//
// Created by WQL on 16/3/1.
// Copyright © 2016年 WQL. All rights reserved.
//
#import "HeartView.h"
//间距
NSInteger const spaceWidth = 5;
//波浪的振幅
NSInteger const waveAmplitude = 5;
@interface HeartView ()
{
CGFloat t;
}
@end
@implementation HeartView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self loadTimer];
}
return self;
}
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
//上面的两个半圆 半径为整个frame的四分之一
CGFloat radius = MIN((self.frame.size.width-spaceWidth*2)/4, (self.frame.size.height-spaceWidth*2)/4);
//左侧圆心 位于左侧边距+半径宽度
CGPoint leftCenter = CGPointMake(spaceWidth+radius, spaceWidth+radius);
//右侧圆心 位于左侧圆心的右侧 距离为两倍半径
CGPoint rightCenter = CGPointMake(spaceWidth+radius*3, spaceWidth+radius);
//左侧半圆
UIBezierPath *heartLine = [UIBezierPath bezierPathWithArcCenter:leftCenter radius:radius startAngle:M_PI endAngle:0 clockwise:YES];
//右侧半圆
[heartLine addArcWithCenter:rightCenter radius:radius startAngle:M_PI endAngle:0 clockwise:YES];
//曲线连接到新的底部顶点 为了弧线的效果,控制点,坐标x为总宽度减spaceWidth,刚好可以相切,平滑过度 y可以根据需要进行调整,y越大,所画出来的线越接近内切圆弧
[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)];
//用曲线 底部的顶点连接到左侧半圆的左起点 为了弧线的效果,控制点,坐标x为spaceWidth,刚好可以相切,平滑过度。y可以根据需要进行调整,y越大,所画出来的线越接近内切圆弧(效果是越胖)
[heartLine addQuadCurveToPoint:CGPointMake(spaceWidth, spaceWidth+radius) controlPoint:CGPointMake(spaceWidth, self.frame.size.height*0.6)];
//线条处理
[heartLine setLineCapStyle:kCGLineCapRound];
//线宽
[self setHeartLineWidthWithPath:heartLine];
//线条的颜色
[self setHeartStrokeColor];
//根据坐标点连线
[heartLine stroke];
//clipToBounds 切掉多余的部分
[heartLine addClip];
//初始化波浪的构成
UIBezierPath *waves = [UIBezierPath bezierPath];
//首先 把起始点设置为左侧 x坐标为spaceWidth 心形从下往上填充,y坐标需要满足一定的函数关系式,当rate为0时,位置为总高度-2倍的留白距离(spaceWidth)+波浪的振幅;当rate为1时,位置为留白距离(spaceWidth)-振幅。由这两个状态构建函数表达式,即可得到如下表达式
CGPoint startPoint = CGPointMake(spaceWidth, (self.frame.size.height-3*spaceWidth+waveAmplitude*2)*(1-self.rate)+spaceWidth-waveAmplitude);
[waves moveToPoint:startPoint];
//关键的地方来了 波浪线怎么画?
//首先,x坐标是从左往右连续的 y坐标是起始的高度加上一定的波动 这里选择了cos函数。5是波动的幅度大小,50控制的是波峰的间距,t是为了让其动起来,随时间发生波动
for (int i = 0; i<self.frame.size.width-spaceWidth*2+self.lineWidth*2; i++) {
//x是要考虑线宽的 不然的话,会导致填充的宽度不够 y就是在某个值附近波动
CGPoint middlePoint = CGPointMake(spaceWidth+i-self.lineWidth, startPoint.y+waveAmplitude*cos(M_PI/50*i+t));
[waves addLineToPoint:middlePoint];
}
//画波浪线的右端 到底部的垂直线
[waves addLineToPoint:CGPointMake(self.frame.size.width-spaceWidth*2, self.frame.size.height-spaceWidth*2)];
//画右侧底部的点 到达左侧底部的点之间的横线
[waves addLineToPoint:CGPointMake(spaceWidth, self.frame.size.height-spaceWidth*2)];