前情提要: 年前公司比较忙,抽间隙时间,搞搞轮子.但是也是由于自己的懒惰,一下班就来个葛优躺,机不离手的刷着头条新闻,微博什么的,一看就是一两个小时,也就懒得再开电脑码字了,本打算节前完成此文章,再看一下上次更新文章的时间,已经一个多月啊,懒惰真是可怕啊.现在已经是二月了,2017的年终终结还只是在计划中,想想自己都笑了,哈哈😁.年后这段时间有点清闲,趁春困还没来,赶紧填上这个坑.不说了,继续码些有用的, 皮皮虾,我们走!!!
先预览一哈效果图

①AlertView(delegate 方式)
虽然苹果公司将 Alertview 和 actionsheet 整合到了一起alertViewController, 但是还是钟情之前的定义方式,现在重新定义样式,使之更有个性.
关键代码
@class SAlertView;/*** 代理方法*/@protocol SAlertViewDelegate <NSObject>@required/*** 代理方法** @param sAlert alertView* @param buttonIndex 点击按钮的 index*/-(void)sAlert:(SAlertView *)sAlert clickedButtonAtIndex:(NSInteger)buttonIndex;@end@interface SAlertView : UIView@property (nonatomic , weak) id<SAlertViewDelegate> delegate;/*** 初始化方法** @param title 标题* @param message 正文* @param cancelButtonTitle 取消* @param otherButtonTitles 确定* @param view 添加alertView的 View* @param delegate id** @return self*/-(instancetype)initWithTitle:( NSString *)title message:( NSString *)message cancelButtonTitle:( NSString *)cancelButtonTitle otherButtonTitles:( NSString *)otherButtonTitles withView:(UIView *) view delegate:(id)delegate;-(void)show;
-(void)showAnimation{self.alpha = 0;self.transform = CGAffineTransformMakeScale(1.5, 1.5);[UIView animateWithDuration:1 delay:0 usingSpringWithDamping:1 initialSpringVelocity:0 options:0animations:^{self.alpha = 1.f;self.transform = CGAffineTransformMakeScale(1, 1);} completion:^(BOOL finished) {}];}-(void)hideAnimation{[UIView animateWithDuration:1 delay:0 usingSpringWithDamping:1 initialSpringVelocity:0 options:0animations:^{self.alpha = 0;self.transform = CGAffineTransformMakeScale(.5, .5);} completion:^(BOOL finished){[self.backView removeFromSuperview];[self removeFromSuperview];}];}
②button(点赞效果)
通过对 layer 层的操作,添加 帧动画和粒子动画,使得效果更加的炫酷.
- (void)animation {//关键帧动画CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];if (self.selected) {keyAnimation.values = @[@1.4 ,@0.9, @1.0,@1.3,@1.0];keyAnimation.duration = 0.4;if (self.isShowAnimation) {[self startShoot];}}else{keyAnimation.values = @[@0.7, @1.0];keyAnimation.duration = 0.3;}// 动画模式keyAnimation.calculationMode = kCAAnimationCubic;[self.imageView.layer addAnimation:keyAnimation forKey:@"transform.scale"];}- (void)startShoot{// 每秒喷射的300个[self.caEmitterLayer setValue:@300 forKeyPath:@"emitterCells.emitterCell.birthRate"];// 开始时间 : 现在立即开始self.caEmitterLayer.beginTime = CACurrentMediaTime();// 0.1秒后停止,相当于立即停止[self performSelector:@selector(stopShoot) withObject:nil afterDelay:0.1];}- (void)stopShoot {[self.caEmitterLayer setValue:@0 forKeyPath:@"emitterCells.emitterCell.birthRate"];}
③actionSheet(Block 方式)
类似微信的样式,参数已经设定好了,可以直接修改值进行调整样式.使用不定长度的参数,进行设置按钮的个数 — otherButtonTitles, … NS_REQUIRES_NIL_TERMINATION,通过va_arg(btnTitle, NSString *)取出各个参数,直到遇到 nil,所以在传入参数时候,最后一定要加上 nil 标志.
-(instancetype)initWithFrame:(CGRect)frame cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION{NSMutableArray * arrayTitle = [NSMutableArray array];//指向参数的指针变量va_list btnTitle;//初始化上面的变量 otherButtonTitles 是可选参数的第一个参数va_start(btnTitle, otherButtonTitles);if(otherButtonTitles){//第一个直接放进数组[arrayTitle addObject:otherButtonTitles];//循环遍历放入数组//返回下一个参数,nsstring 为类型, 并指向下一个参数while ((otherButtonTitles = va_arg(btnTitle, NSString *))) {[arrayTitle addObject:otherButtonTitles];}}//释放指针变量va_end(btnTitle);if (self = [super initWithFrame:frame]) {_arrayCount = arrayTitle.count;[self addSubview:self.bgView];//按钮的背景_btnBGView = [[UIView alloc]initWithFrame:(CGRect){0,HEIGHTOFSCREEN ,WIDTHOFSCREEN,(arrayTitle.count + 1 ) * 50 + 5 }];_btnBGView.backgroundColor = setRGBColor(233, 233, 233, 1.0);[self addSubview:_btnBGView];//创建按钮组for (int i = 0 ;i <= arrayTitle.count ; i++) {UIButton * btn = [[UIButton alloc]initWithFrame:(CGRect){0, 50.5 * i,WIDTHOFSCREEN,50}];btn.backgroundColor = [UIColor whiteColor];btn.tag = i ;[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[btn addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];if (i != arrayTitle.count) {[btn setTitle:arrayTitle[i] forState:UIControlStateNormal];}else{btn.frame = (CGRect){0, 50.5 * i + 5,WIDTHOFSCREEN,50};[btn setTitle:cancelButtonTitle forState:UIControlStateNormal];}[_btnBGView addSubview:btn];}}return self;}
④label
类似QQ 空间的会员的炫酷名称,有一个炫光从左至右的扫过,颜色可以自己设置,使用的渐变色进行渲染.
-(void)setFlushStyle:(BOOL) isFlush{self.gradientLayer.frame = CGRectMake( 0,0,self.frame.size.width,self.frame.size.height);NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];style.alignment = NSTextAlignmentLeft;//开始UIGraphicsBeginImageContextWithOptions(self.frame.size, false, 0);[self.text drawInRect:self.bounds withAttributes:@{NSParagraphStyleAttributeName:style , NSFontAttributeName: self.font}];//获取当前UIImage *image = UIGraphicsGetImageFromCurrentImageContext();//结束UIGraphicsEndImageContext();CALayer * maskLayer = [CALayer layer];maskLayer.backgroundColor = [UIColor clearColor].CGColor;maskLayer.frame = CGRectOffset((CGRect){0,0,self.frame.size}, 0, 0);maskLayer.contents = (id)image.CGImage;self.gradientLayer.mask = maskLayer;if (isFlush)[self.layer addSublayer: self.gradientLayer];else[self.layer addSublayer:maskLayer];CABasicAnimation * basicAnim = [CABasicAnimation animationWithKeyPath:@"locations"];basicAnim.fromValue = @[@0.0, @0.0, @0.25];basicAnim.toValue = @[@0.75, @1.0, @1.0];basicAnim.duration = 2.8;basicAnim.repeatCount = CGFLOAT_MAX;basicAnim.removedOnCompletion = NO;[self.gradientLayer addAnimation:basicAnim forKey:nil];}
⑤button(消息数显示和清除)
类似QQ 的消息清除,直接拖拽,可以消除消息提示.主要使用贝塞尔曲线的绘制粘性体
/** 绘制贝赛尔曲线方法*/- (void)drawBezierLine {//定义一个角度 Θ 正余弦: sinΘ = (x2 - x1)/distance ,cosΘ = (y2 - y1)/distanceCGFloat sinΘ = (self.x2 - self.x1)/ self.remoteDistance;CGFloat cosΘ = (self.y2 - self.y1)/ self.remoteDistance;CGPoint pointA = (CGPoint){ self.x1 - r* cosΘ* self.scale, self.y1 + r* sinΘ* self.scale };CGPoint pointB = (CGPoint){ self.x1 + r* cosΘ* self.scale, self.y1 - r* sinΘ* self.scale };CGPoint pointC = (CGPoint){ self.x2 + R* cosΘ, self.y2 - R* sinΘ };CGPoint pointD = (CGPoint){ self.x2 - R* cosΘ, self.y2 + R* sinΘ };CGPoint pointE = (CGPoint){ pointA.x + self.remoteDistance *.5 * sinΘ , pointA.y + self.remoteDistance* .5* cosΘ}; //控制点1,与不动的 view 的半径垂直CGPoint pointF = (CGPoint){ pointB.x + self.remoteDistance *.5 * sinΘ , pointB.y + self.remoteDistance* .5* cosΘ }; //控制点2,与不动的 view 的半径垂直// 设 pointG (x, y),// 已知(x1,y1),(x2,y2)/* ①x1 - x2 x - x2--------- = --------y1 - y2 y - y2②R² = (x - x2)² + (y - y2)² 可以得出(x , y)*/CGPoint pointG = CGPointZero;CGFloat pointGY = sqrtf( R*R*4/(((self.x1 - self.x2 ) / (self.y1 - self.y2))*((self.x1 - self.x2 ) / (self.y1 - self.y2)) + 1)) + self.y2;CGFloat pointGX = (pointGY - self.y2) * (self.x1 - self.x2 ) / (self.y1 - self.y2) + self.x2;CGFloat distance = sqrtf((self.x1 - pointGX)*(self.x1 - pointGX) + (self.y1 - pointGY)*(self.y1 - pointGY));if (distance < self.remoteDistance) {pointG = (CGPoint){ pointGX, pointGY };}else{pointG = (CGPoint){ 2* self.x2 - pointGX, 2*self.y2 - pointGY };}UIBezierPath * bezierPath = [UIBezierPath bezierPath];//起点[bezierPath moveToPoint:pointA];//直线[bezierPath addLineToPoint:pointB];//曲线[bezierPath addQuadCurveToPoint:pointC controlPoint:pointF];//直线//[bezierPath addLineToPoint:pointD];[bezierPath addQuadCurveToPoint:pointD controlPoint:pointG];//曲线[bezierPath addQuadCurveToPoint:pointA controlPoint:pointE];self.shapelayer.path = [bezierPath CGPath];[self.layer addSublayer:self.shapelayer];}
结尾的结尾: 年关已过,又是一个春天,何不趁着春风,来一次旅行呢?我在北京,欢迎你~🍻
