当前位置: 代码迷 >> 综合 >> IOS开发教程第一季之UI进阶day8合并IOS学习019--敲击、长按、轻扫、旋转,CALayer、锚点,CADisolayLink刷新,核心动画,关键帧动画,组动画,转场动画,画板案例
  详细解决方案

IOS开发教程第一季之UI进阶day8合并IOS学习019--敲击、长按、轻扫、旋转,CALayer、锚点,CADisolayLink刷新,核心动画,关键帧动画,组动画,转场动画,画板案例

热度:66   发布时间:2024-01-31 22:06:45.0
1.创建并实现手势的基本步骤

点击手势

#import "ViewController.h"@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageview;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//1.创建点击手势UITapGestureRecognizer* tap=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];//更改点击的次数tap.numberOfTapsRequired=2;//点击两次才会触发方法tap.numberOfTouchesRequired=2;//几根手指点几次//2、对某一个view添加收拾[self.imageview addGestureRecognizer:tap];}//3、实现手势放方法
-(void)tap:(UITapGestureRecognizer*) sender{NSLog(@"你点击手势了");}
@end

长按手势

#import "ViewController.h"@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageview;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//1.创建点击手势UILongPressGestureRecognizer* longpress=[[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longpress:)];//更改长按的时间longpress.minimumPressDuration=3;//长按多少时间longpress.allowableMovement=10;//手指误差范围10个点//2、对某一个view添加收拾[self.imageview addGestureRecognizer:longpress];}//3、实现手势放方法
-(void)longpress:(UILongPressGestureRecognizer*) sender{//如果是第一次长按if (sender.state==UIGestureRecognizerStateBegan) {NSLog(@"你长按了");}}
@end

轻扫手势(默认从左往右扫)

#import "ViewController.h"@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageview;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//1.创建点击手势UISwipeGestureRecognizer* swipe1=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];UISwipeGestureRecognizer* swipe2=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];//更改轻扫方向swipe1.direction=UISwipeGestureRecognizerDirectionLeft;//从右往左swipe2.direction=UISwipeGestureRecognizerDirectionRight;//从左往右//2、对某一个view添加收拾[self.imageview addGestureRecognizer:swipe1];[self.imageview addGestureRecognizer:swipe2];}//3、实现手势放方法
-(void)swipe:(UISwipeGestureRecognizer*) sender{//判断轻扫方向if (sender.direction==UISwipeGestureRecognizerDirectionLeft) {NSLog(@"你从右往左轻扫了");}else{NSLog(@"你从左往右轻扫了");}
}
@end

旋转手势

#import "ViewController.h"@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageview;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//1.创建旋转手势UIRotationGestureRecognizer* rotation=[[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotation:)];//更改轻扫方向//swipe1.direction=UISwipeGestureRecognizerDirectionLeft;//从右往左//2、对某一个view添加收拾[self.imageview addGestureRecognizer:rotation];}//3、实现手势放方法
-(void)rotation:(UIRotationGestureRecognizer*) sender{//判断轻扫方向self.imageview.transform=CGAffineTransformRotate(self.imageview.transform, sender.rotation);NSLog(@"%f",sender.rotation);//使得sender每次穿过来的rotation是一个夹角sender.rotation=0;}
@end

捏合手势

#import "ViewController.h"@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageview;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//1.创建捏合手势(缩放)UIPinchGestureRecognizer* pinch=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinch:)];//2、对某一个view添加手势[self.imageview addGestureRecognizer:pinch];}//3、实现手势放方法
-(void)pinch:(UIPinchGestureRecognizer*) sender{self.imageview.transform=CGAffineTransformScale(self.imageview.transform, sender.scale, sender.scale);NSLog(@"%f",sender.scale);sender.scale=1;}
@end

拖拽手势

#import "ViewController.h"@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageview;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//1.创建拓转手势(平移)UIPanGestureRecognizer* pan=[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pan:)];//2、对某一个view添加手势[self.imageview addGestureRecognizer:pan];}//3、实现手势放方法
-(void)pan:(UIPanGestureRecognizer*) sender{CGPoint point=[sender translationInView:sender.view];//sender.view是做手势的那个viewself.imageview.transform=CGAffineTransformTranslate(self.imageview.transform, point.x, point.y);[sender setTranslation:CGPointZero inView:sender.view];}
@end

多手势共用,使用代理

#import "ViewController.h"@interface ViewController ()<UIGestureRecognizerDelegate>
@property (weak, nonatomic) IBOutlet UIImageView *imageview;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//1.创建旋转手势UIRotationGestureRecognizer* rotation=[[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotation:)];//2、对某一个view添加收拾[self.imageview addGestureRecognizer:rotation];//创建旋转的代理方法解决手势冲突的问题rotation.delegate=self;//1.创建捏合手势(缩放)UIPinchGestureRecognizer* pinch=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinch:)];pinch.delegate=self;//2、对某一个view添加手势[self.imageview addGestureRecognizer:pinch];}
//实现代理方法,解决手势冲突
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{return YES;
}//3、实现手势放方法
//旋转方法
-(void)rotation:(UIRotationGestureRecognizer*) sender{//判断轻扫方向self.imageview.transform=CGAffineTransformRotate(self.imageview.transform, sender.rotation);NSLog(@"%f",sender.rotation);//使得sender每次穿过来的rotation是一个夹角sender.rotation=0;}
//捏合方法
-(void)pinch:(UIPinchGestureRecognizer*) sender{self.imageview.transform=CGAffineTransformScale(self.imageview.transform, sender.scale, sender.scale);NSLog(@"%f",sender.scale);sender.scale=1;}@end
2.CALayer的基本属性

view内部以图层形式(CAlayer)显示内容,实际上view负责监听,calayer负责显示

通过calayer可以调整许多view的效果,比如,边框、阴影、大小

#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//创建一个viewUIView* redview=[[UIView alloc]init];redview.frame=CGRectMake(150, 150, 100, 100);redview.backgroundColor=[UIColor greenColor];//设置边框redview.layer.borderWidth=5;//边框宽度,同时内容部分要减去10个点redview.layer.borderColor=[UIColor blueColor].CGColor;//边框阴影,颜色要转化为cg颜色//设置阴影redview.layer.shadowOffset=CGSizeMake(5, 5);//阴影偏移量redview.layer.shadowColor=[UIColor grayColor].CGColor;//阴影颜色redview.layer.shadowOpacity=1;//阴影透明度,1为不透明redview.layer.shadowRadius=5;//阴影的半径//设置圆角redview.layer.cornerRadius=15;//圆角半径//redview.layer.masksToBounds=YES;//超出layer的范围就不显示,实际上消除阴影//redview.layer.frame=CGRectMake(0, 0, 300, 300);//慎用,易出问题//bounds大小redview.layer.bounds=CGRectMake(50, 60, 200, 200);//position位置属性和view.center的关系//redview.layer.position=CGPointMake(0, 0);//实际是view.center中心点跑到point的位置上//设置内容图片redview.layer.contents=(__bridge id)([UIImage imageNamed:@"33"].CGImage);//将c的对象转换成oc对象[self.view addSubview:redview];
}@end

效果
在这里插入图片描述

3.手动创建Layer
#import "ViewController.h"@interface ViewController ()
@property(nonatomic,weak)CALayer* layer;
@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//创建一个layer对象CALayer* mylayer=[[CALayer alloc]init];mylayer.backgroundColor=[UIColor greenColor].CGColor;mylayer.position=CGPointMake(200, 200);mylayer.bounds=CGRectMake(0, 0, 100,100);//将layer添加到控制器的layer上[self.view.layer addSublayer:mylayer];//给全局说行赋值self.layer=mylayer;}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{//获取触摸对象UITouch* touch=touches.anyObject;//获取手指当前的位置CGPoint point=[touch locationInView:touch.view];//禁用隐式动画(类似于数据库的事务,需要开启之后再提交)[CATransaction begin];//开启事务[CATransaction setDisableActions:YES];//禁用隐式动画//让layer跑到手指的位置,这里会产生一个隐式动画,而根layer没有隐式动画self.layer.position=point;//位置self.layer.opacity*=0.9;//透明度[CATransaction commit];//提交事务
}
@end
4.锚点(anchorPoint)示意图

anchor的取值范围在0-1。实质anchorPoint就是这个对象的定位点,用来取代原先中心点,实质就是将中心点替换为anchorPoint锚点。
在这里插入图片描述

5.时钟案例—添加一个表盘
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// 用calayer创建一个表盘CALayer* clock=[[CALayer alloc]init];//设置layer尺寸clock.bounds=CGRectMake(0, 0, 200, 200);//设置layer大小clock.position=CGPointMake(200, 200);//设置图片clock.contents=(__bridge id)([UIImage imageNamed:@"clock"].CGImage);//设置圆角clock.cornerRadius=100;clock.masksToBounds=YES;//切角//添加创建秒钟CALayer* second=[[CALayer alloc]init];second.bounds=CGRectMake(0, 0, 2, 60);//大小second.position=clock.position;//与时钟的位置相等second.backgroundColor=[UIColor redColor].CGColor;//设置指针的锚点(anchorPoint定位点)second.anchorPoint=CGPointMake(0.5, 0.8);//注意下添加的顺序,免得被遮挡[self.view.layer addSublayer:clock];[self.view.layer addSublayer:second];}@end

在这里插入图片描述

6.时钟案例—设置事件间隔
#import "ViewController.h"@interface ViewController ()
@property(nonatomic,weak)CALayer* second;
@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// 用calayer创建一个表盘CALayer* clock=[[CALayer alloc]init];//设置layer尺寸clock.bounds=CGRectMake(0, 0, 200, 200);//设置layer大小clock.position=CGPointMake(200, 200);//设置图片clock.contents=(__bridge id)([UIImage imageNamed:@"clock"].CGImage);//设置圆角clock.cornerRadius=100;clock.masksToBounds=YES;//切角//添加创建秒钟CALayer* second=[[CALayer alloc]init];second.bounds=CGRectMake(0, 0, 2, 60);//大小second.position=clock.position;//与时钟的位置相等second.backgroundColor=[UIColor redColor].CGColor;//设置指针的锚点(anchorPoint定位点)second.anchorPoint=CGPointMake(0.5, 0.8);//注意下添加的顺序,免得被遮挡//添加表盘[self.view.layer addSublayer:clock];//添加秒针[self.view.layer addSublayer:second];self.second=second;//创建一个定时器[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeChange) userInfo:nil repeats:YES];[self timeChange];//让第一秒钟就跟随系统时间}
//旋转方法
-(void)timeChange{//一秒钟旋转的角度CGFloat angle=2*M_PI/60;//获取当前时间的秒数NSDate* date=[NSDate date];//创建一个时间格式化对象/*第一种取时间的方法NSDateFormatter* formatter=[[NSDateFormatter alloc]init];formatter.dateFormat=@"ss";CGFloat time=[[formatter stringFromDate:date]floatValue];//秒针旋转到某个角度self.second.affineTransform=CGAffineTransformMakeRotation(time*angle);*///日历对象来获取时间NSCalendar* cal=[NSCalendar currentCalendar];//获取当前日期CGFloat time=[cal component:NSCalendarUnitSecond fromDate:date];//拿到日期的秒数//秒针旋转到某个角度self.second.affineTransform=CGAffineTransformMakeRotation(time*angle);
}@end

在这里插入图片描述

7.时钟案例—设置屏幕刷新(CADisplayLink)
#import "ViewController.h"@interface ViewController ()
@property(nonatomic,weak)CALayer* second;
@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// 用calayer创建一个表盘CALayer* clock=[[CALayer alloc]init];//设置layer尺寸clock.bounds=CGRectMake(0, 0, 200, 200);//设置layer大小clock.position=CGPointMake(200, 200);//设置图片clock.contents=(__bridge id)([UIImage imageNamed:@"clock"].CGImage);//设置圆角clock.cornerRadius=100;clock.masksToBounds=YES;//切角//添加创建秒钟CALayer* second=[[CALayer alloc]init];second.bounds=CGRectMake(0, 0, 2, 60);//大小second.position=clock.position;//与时钟的位置相等second.backgroundColor=[UIColor redColor].CGColor;//设置指针的锚点(anchorPoint定位点)second.anchorPoint=CGPointMake(0.5, 0.8);//注意下添加的顺序,免得被遮挡//添加表盘[self.view.layer addSublayer:clock];//添加秒针[self.view.layer addSublayer:second];self.second=second;//显示连接(CADisplayLink)CADisplayLink* link=[CADisplayLink displayLinkWithTarget:self selector:@selector(timeChange)];//把连接添加到主运行循环[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];[self timeChange];//让第一秒钟就跟随系统时间}
//旋转方法
-(void)timeChange{//一秒钟旋转的角度CGFloat angle=2*M_PI/60;//获取当前时间的秒数NSDate* date=[NSDate date];//日历对象来获取时间NSCalendar* cal=[NSCalendar currentCalendar];//获取当前日期CGFloat time=[cal component:NSCalendarUnitSecond fromDate:date];//拿到日期的秒数//秒针旋转到某个角度self.second.affineTransform=CGAffineTransformMakeRotation(time*angle);
}@end
7.核心动画简介

CoreAnitmation的动画执行过程都在后台操作,不会阻塞主线程
core Antimation是直接作用在CALayer上的,并非UIView
CAAnimation继承结构
在这里插入图片描述

8.基本动画
#import "ViewController.h"@interface ViewController ()
@property(nonatomic,weak)CALayer* layer;
@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//创建一个视图UIView* redview=[[UIView alloc]init];redview.frame=CGRectMake(100, 100, 100, 100);redview.backgroundColor=[UIColor greenColor];self.layer=redview.layer;[self.view addSubview:redview];
}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{//基本动画//创建动画CABasicAnimation* animation=[[CABasicAnimation alloc]init];//怎么做动画//基本动画都是修改属性获得的动画animation.keyPath=@"position.y";//动画更改的某个属性//animation.fromValue=@(10);//动画的某个属性值变动范围终点//animation.toValue=@(300);//动画的某个属性值变动范围终点animation.byValue=@(10);//自身的基础上+一定地址//不希望动画播放完后回到起始位置animation.fillMode=kCAFillModeForwards;animation.removedOnCompletion=NO;//添加动画(对谁做动画)[self.layer addAnimation:animation forKey:nil];}@end
9.关键帧动画

设置关键节点运动

#import "ViewController.h"@interface ViewController ()
@property(nonatomic,weak)CALayer* layer;
@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//创建一个视图UIView* redview=[[UIView alloc]init];redview.frame=CGRectMake(100, 100, 20, 20);redview.backgroundColor=[UIColor greenColor];self.layer=redview.layer;[self.view addSubview:redview];
}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{//关键帧动画//创建动画CAKeyframeAnimation* animation=[[CAKeyframeAnimation alloc]init];//怎么做动画//基本动画都是修改属性获得的动画animation.keyPath=@"position";//动画更改的某个属性,这个keypath是一个cgPoint对象NSValue* value1=[NSValue valueWithCGPoint:CGPointMake(100, 100)];//关键帧的位置NSValue* value2=[NSValue valueWithCGPoint:CGPointMake(150, 100)];NSValue* value3=[NSValue valueWithCGPoint:CGPointMake(100, 150)];NSValue* value4=[NSValue valueWithCGPoint:CGPointMake(150, 150)];//设置若干个关键点(帧)animation.values=@[value1,value2,value3,value4];//设置动画完成的时间animation.duration=2;//4秒完成时间//设置动画实现次数animation.repeatCount=INT_MAX;//添加动画(对谁做动画)[self.layer addAnimation:animation forKey:nil];}@end

围绕圆圈运动

#import "ViewController.h"@interface ViewController ()
@property(nonatomic,weak)CALayer* layer;
@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//创建一个视图UIView* redview=[[UIView alloc]init];redview.frame=CGRectMake(100, 100, 20, 20);redview.backgroundColor=[UIColor greenColor];self.layer=redview.layer;[self.view addSubview:redview];
}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{//关键帧动画//创建关键帧动画,绕着圆的路径走CAKeyframeAnimation* animationRatation=[[CAKeyframeAnimation alloc]init];//怎么做动画//常见引导路径animationRatation.keyPath=@"position";UIBezierPath* path=[UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:2*M_PI clockwise:YES];//将自定义路径设置给动画的路径(关键点路径)animationRatation.path=path.CGPath;//设置动画完成的时间animation.duration=2;//4秒完成时间//设置动画实现次数animation.repeatCount=INT_MAX;//添加动画(对谁做动画)[self.layer addAnimation:animation forKey:nil];}@end
10.组动画(多个动画共同执行)
#import "ViewController.h"@interface ViewController ()
@property(nonatomic,weak)CALayer* layer;
@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//创建一个视图UIView* redview=[[UIView alloc]init];redview.frame=CGRectMake(100, 100, 20, 20);redview.backgroundColor=[UIColor greenColor];self.layer=redview.layer;[self.view addSubview:redview];
}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{//组动画//创建动画CAAnimationGroup* group=[[CAAnimationGroup alloc]init];//创建基本动画----------------------------CABasicAnimation* animationTransform=[[CABasicAnimation alloc]init];//基本动画都是修改属性获得的动画animationTransform.keyPath=@"transform.rotation";//动画更改的旋转属性animationTransform.byValue=@(2*M_PI);//自身的基础上旋转//创建关键帧动画,绕着圆的路径走----------------------CAKeyframeAnimation* animationRatation=[[CAKeyframeAnimation alloc]init];//常见引导路径animationRatation.keyPath=@"position";UIBezierPath* path=[UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:2*M_PI clockwise:YES];//设置关键帧动画的关键路径animationRatation.path=path.CGPath;//-------------------------------//组动画怎么做动画group.animations=@[animationTransform,animationRatation];//放入一个关键帧动画和一个基本动画,其实就是符合动画,//设置组动画完成的时间group.duration=2;//4秒完成时间//设置组动画实现次数group.repeatCount=INT_MAX;//添加动画(对谁做动画)[self.layer addAnimation:group forKey:nil];}@end
11.转场动画(类似ppt幻灯片转场)

在故事板stroyboard上添加手势的步骤
1、storyboard中添加一个imageView
2、将手势拖拽到imageview上
3、将刚才添加的手势拖线到ViewController上

转场动画过渡效果
在这里插入图片描述

#import "ViewController.h"@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property(nonatomic,assign)NSInteger imageName;@end@implementation ViewController
//轻扫手势执行的方法
- (IBAction)imageChage:(UISwipeGestureRecognizer*)sender {self.imageName++;//图片名++,因为图片的名字为1,2,3,4,5//让图片名循环起来if (self.imageName==5) {self.imageName=0;}self.imageView.image=[UIImage imageNamed:[NSString stringWithFormat:@"%ld",self.imageName+1] ];//1创建一个动画CATransition* animation=[[CATransition alloc]init];//2、操作动画某个属性animation.type=@"cube";//立方体变幻属性if (sender.direction==UISwipeGestureRecognizerDirectionLeft) {//如果方向往左animation.subtype=kCATransitionFromRight;//设置变化属性的次样式,这里是立方变幻的想做变化}else{animation.subtype=kCATransitionFromLeft;//设置变化属性的次样式,这里是立方变幻的想做变化}//3添加动画[self.imageView.layer addAnimation:animation forKey:nil];
}- (void)viewDidLoad {[super viewDidLoad];self.imageName=0;
}
@end
12.画板案例–绘制界面及实现绘图,

绘图区域为一个view设置FRView类与之对应

#import "FRView.h"
@interface FRView()
@property(nonatomic,strong)UIBezierPath* path;@end
@implementation FRView#define mark ------懒加载数据--------
//重新path的get方法
-(UIBezierPath*)path{if (!_path) {_path=[[UIBezierPath alloc]init];}return _path;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{//获取触摸对象UITouch* touch=touches.anyObject;//创建起点//获取手指的位置CGPoint point=[touch locationInView:touch.view];//获取起点,手指移动到起点上[self.path moveToPoint:point];
}- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{//添加到点//获取触摸对象UITouch* touch=touches.anyObject;//获取手指的位置CGPoint point=[touch locationInView:touch.view];//绘制的终点[self.path addLineToPoint:point];//重绘路径[self setNeedsDisplay];
}- (void)drawRect:(CGRect)rect{[self.path stroke];
}@end

在这里插入图片描述

13.画板案例–增加线宽

FRView.h

#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface FRView : UIView
@property(nonatomic,assign)CGFloat lineWidth;@endNS_ASSUME_NONNULL_END

FRView.m

#import "FRView.h"
@interface FRView()
//管理路径的数组
@property(nonatomic,strong)NSMutableArray* paths;
@end
@implementation FRView#define mark -------懒加载----------
//重写paths的get方法
-(NSMutableArray*)paths{if (!_paths) {_paths=[NSMutableArray array];}return _paths;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{//获取触摸对象UITouch* touch=touches.anyObject;//创建起点//获取手指的位置CGPoint point=[touch locationInView:touch.view];//创建路径UIBezierPath* path=[[UIBezierPath alloc]init];//设置线宽[path setLineWidth:self.lineWidth];//获取起点,手指移动到起点上[path moveToPoint:point];//将每一次创建的路径加载到路径数组上[self.paths addObject:path];
}- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{//添加到点//获取触摸对象UITouch* touch=touches.anyObject;//获取手指的位置CGPoint point=[touch locationInView:touch.view];//创建路径UIBezierPath* path=[[UIBezierPath alloc]init];//绘制的终点[[self.paths lastObject] addLineToPoint:point];//重绘路径[self setNeedsDisplay];
}- (void)drawRect:(CGRect)rect{//渲染路径for (UIBezierPath* path in self.paths) {//设置头尾和连接处的样式[path setLineJoinStyle:kCGLineJoinRound];[path setLineCapStyle:kCGLineCapRound];//渲染路径[path stroke];}
}
@end

ViewController.m

#import "ViewController.h"
#import "FRView.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UISlider *lineWidthProgress;@property (weak, nonatomic) IBOutlet FRView *frview;
//监听线宽改变
- (IBAction)lineWithChange:(UISlider*)sender;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//设置初始线宽self.frview.lineWidth=self.lineWidthProgress.value;
}//监听线宽改变- (IBAction)lineWithChange:(UISlider*)sender {//把最新的数值(线宽)给了frviewself.frview.lineWidth =sender.value;
}
@end

在这里插入图片描述

14.画板案例–设置画笔颜色
  • 需要专门为路径颜色写一个类FRBezierPath,继承UIBezierPath,并新增一个lineColor1属性,以后创建路径时使用FRFRBezierPath进行创建,这样创建的路径就具备了setLinerColor的写方法。
  • 实际使用时可以将按钮的背景色传递个这个自定义path的setLinerColor方法。
  • 最后在drawrect方法中为路径设置颜色 [path.lineColor set]
    FRBezierpath.h
#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface FRBezierpath : UIBezierPath
@property(nonatomic,strong)UIColor* lineColor1;
@endNS_ASSUME_NONNULL_END

FRBezierpath.m

#import "FRBezierpath.h"@implementation FRBezierpath@end

FRView.h

#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface FRView : UIView
@property(nonatomic,assign)CGFloat lineWidth;
@property(nonatomic,strong)UIColor* lineColor;@endNS_ASSUME_NONNULL_END

FRView.m

#import "FRView.h"
#import "FRBezierpath.h"
@interface FRView()
//管理路径的数组
@property(nonatomic,strong)NSMutableArray* paths;
@end
@implementation FRView#define mark -------懒加载----------
//重写paths的get方法
-(NSMutableArray*)paths{if (!_paths) {_paths=[NSMutableArray array];}return _paths;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{//获取触摸对象UITouch* touch=touches.anyObject;//创建起点//获取手指的位置CGPoint point=[touch locationInView:touch.view];//创建路径FRBezierpath* path=[[FRBezierpath alloc]init];//设置线宽[path setLineWidth:self.lineWidth];[path setLineColor1:self.lineColor];//设置自定义的颜色//获取起点,手指移动到起点上[path moveToPoint:point];//将每一次创建的路径加载到路径数组上[self.paths addObject:path];
}- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{//添加到点//获取触摸对象UITouch* touch=touches.anyObject;//获取手指的位置CGPoint point=[touch locationInView:touch.view];//创建路径FRBezierpath* path=[[FRBezierpath alloc]init];//绘制的终点[[self.paths lastObject] addLineToPoint:point];//重绘路径[self setNeedsDisplay];
}- (void)drawRect:(CGRect)rect{//渲染路径for (FRBezierpath* path in self.paths) {//设置头尾和连接处的样式[path setLineJoinStyle:kCGLineJoinRound];[path setLineCapStyle:kCGLineCapRound];//在这里绘制颜色[path.lineColor1 set];//渲染路径[path stroke];}
}
@end

ViewController.m

#import "ViewController.h"
#import "FRView.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UISlider *lineWidthProgress;
@property (weak, nonatomic) IBOutlet FRView *frview;- (IBAction)lineColorChange:(UIButton*)sender;//监听线宽改变
- (IBAction)lineWithChange:(UISlider*)sender;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//设置初始线宽self.frview.lineWidth=self.lineWidthProgress.value;
}//监听线宽改变
- (IBAction)lineWithChange:(UISlider*)sender {//把最新的数值(线宽)给了frviewself.frview.lineWidth =sender.value;
}
//监听颜色的改变
- (IBAction)lineColorChange:(UIButton*)sender {self.frview.lineColor=sender.backgroundColor;
}
@end

在这里插入图片描述

15.画板案例–画板工具条

FRBezierpath.h

#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface FRBezierpath : UIBezierPath
@property(nonatomic,strong)UIColor* lineColor1;
@endNS_ASSUME_NONNULL_END

FRBezierpath.m

#import "FRBezierpath.h"@implementation FRBezierpath@end

FRView.h

#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface FRView : UIView
@property(nonatomic,assign)CGFloat lineWidth;
@property(nonatomic,strong)UIColor* lineColor;
//橡皮擦除
- (void)erase;
//回退
- (void)back;
//清屏
- (void)clear;
@endNS_ASSUME_NONNULL_END

FRView.m

#import "FRView.h"
#import "FRBezierpath.h"
@interface FRView()
//管理路径的数组
@property(nonatomic,strong)NSMutableArray* paths;
@end
@implementation FRView#define mark -------懒加载----------
//重写paths的get方法
-(NSMutableArray*)paths{if (!_paths) {_paths=[NSMutableArray array];}return _paths;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{//获取触摸对象UITouch* touch=touches.anyObject;//创建起点//获取手指的位置CGPoint point=[touch locationInView:touch.view];//创建路径FRBezierpath* path=[[FRBezierpath alloc]init];//设置线宽[path setLineWidth:self.lineWidth];[path setLineColor1:self.lineColor];//设置自定义的颜色//获取起点,手指移动到起点上[path moveToPoint:point];//将每一次创建的路径加载到路径数组上[self.paths addObject:path];
}- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{//添加到点//获取触摸对象UITouch* touch=touches.anyObject;//获取手指的位置CGPoint point=[touch locationInView:touch.view];//创建路径FRBezierpath* path=[[FRBezierpath alloc]init];//绘制的终点[[self.paths lastObject] addLineToPoint:point];//重绘路径[self setNeedsDisplay];
}- (void)drawRect:(CGRect)rect{//渲染路径for (FRBezierpath* path in self.paths) {//设置头尾和连接处的样式[path setLineJoinStyle:kCGLineJoinRound];[path setLineCapStyle:kCGLineCapRound];//在这里绘制颜色[path.lineColor1 set];//渲染路径[path stroke];}
}//橡皮擦除
- (void)erase{self.lineColor=self.backgroundColor;
}
//回退
- (void)back{//删除路径数组里面的最后一个路径[self.paths removeLastObject];[self setNeedsDisplay];
}
//清屏
- (void)clear{//删除路径数组里面的所有路径[self.paths removeAllObjects];[self setNeedsDisplay];
}
@end

ViewController.m

#import "ViewController.h"
#import "FRView.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UISlider *lineWidthProgress;
@property (weak, nonatomic) IBOutlet FRView *frview;
- (IBAction)save:(id)sender;- (IBAction)lineColorChange:(UIButton*)sender;
- (IBAction)clear:(id)sender;
- (IBAction)back:(id)sender;
- (IBAction)erase:(id)sender;//监听线宽改变
- (IBAction)lineWithChange:(UISlider*)sender;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];//设置初始线宽self.frview.lineWidth=self.lineWidthProgress.value;
}//监听线宽改变
- (IBAction)lineWithChange:(UISlider*)sender {//把最新的数值(线宽)给了frviewself.frview.lineWidth =sender.value;
}
//橡皮擦除
- (IBAction)erase:(id)sender {[self.frview erase];
}
//回退
- (IBAction)back:(id)sender {[self.frview back];}
//清屏
- (IBAction)clear:(id)sender {[self.frview clear];}
//监听颜色的改变- (IBAction)lineColorChange:(UIButton*)sender {self.frview.lineColor=sender.backgroundColor;
}
//保存到相册
- (IBAction)save:(id)sender {//开启图片类型的上下文UIGraphicsBeginImageContextWithOptions(self.frview.bounds.size, NO,0);//获取上下文CGContextRef ctx=UIGraphicsGetCurrentContext();//截图[self.frview.layer renderInContext:ctx];//取图片UIImage * image=UIGraphicsGetImageFromCurrentImageContext();//保存到相册UIImageWriteToSavedPhotosAlbum(image, NULL, NULL, NULL);//IOS的高版本会要求隐私权限,所以这个步骤并不能真的保存
}
@end

在这里插入图片描述