欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2022-03-28 16:14:42
1.创建并实现手势的基本步骤点击手势#import "ViewController.h"@interface ViewController ()@property (weak, nonatomic) IBOutlet UIImageView *imageview;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //1.创建点击手势 UITapGestureRecogni...
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是做手势的那个view
  
  self.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];
  //创建一个view
  UIView* 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

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

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

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

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

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

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

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

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上

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

#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

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

13.画板案例–增加线宽

FRView.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface FRView : UIView
@property(nonatomic,assign)CGFloat lineWidth;

@end

NS_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 {
  //把最新的数值(线宽)给了frview
  self.frview.lineWidth =sender.value;
}
@end

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

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;
@end

NS_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;

@end

NS_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 {
  //把最新的数值(线宽)给了frview
  self.frview.lineWidth =sender.value;
}
//监听颜色的改变
- (IBAction)lineColorChange:(UIButton*)sender {
  self.frview.lineColor=sender.backgroundColor;
}
@end

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

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

FRBezierpath.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface FRBezierpath : UIBezierPath
@property(nonatomic,strong)UIColor* lineColor1;
@end

NS_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;
@end

NS_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 {
  //把最新的数值(线宽)给了frview
  self.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

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

本文地址:https://blog.csdn.net/weixin_43745804/article/details/107547736