这是我参与「第四届青训营 -iOS场」笔记创作活动的的第5篇笔记
交互与手势
- 以前关于手势的记录,里面有基本的使用
- 手势识别器的类
- UITapGestureRecognizer 点按
- UILongPressGestureRecognizer 长按
- UISwipeGestureRecognizer 轻扫
- UIRotationGestureRecognizer 旋转
- UIPinchGestureRecognizer 捏合
- UIPanGestureRecognizer 拖拽
- 通过
UIGestureRecognizerDelegate,可以约束手势响应时机
手势原理
- iOS交互事件
- 触摸事件
- 运动事件
- 远程事件
- UITouch,抽象了手指触摸屏幕的一个类,每一个实例代表手指的一次处理,携带位置、大小等信息
- 根据上下文信息,生成UIEvent对象,抽象了由一个或者多个UITouch所造成的一个事件;每一个实例代表一个触摸事件,比如单击事件,长按事件
- 生成之后,将UITouch和UIEvent发送给UIResponder,进行响应和处理事件;当有事件发生,系统会去寻找最合适的UIResponder,进行通知
- 收到事件后,App将Event发送给keyWindow(根视图),由根视图开始遍历查找响应者视图
- UIView通过
hitTest:withEvent判断响应者,通过userInteractionEnabled(是否能交互)、hidden(是否被隐藏)、alpha(透明度是否为0)判断自身是否能响应;pointInside:withEvent判断触摸点是否在自己frame范围内;从后往前依次递归子视图,如果都没有就返回自己
动画
- 以前关于动画的记录,里面有基本的使用
- 动画本质,就是连续播放的很多帧静态图片,利用人的视觉残影
block动画
- 基本使用
UIView *animationView = [[UIView alloc] initWithFrame:CGRectMake(5, 5, 100, 100)];
animationView.backgroundColor = [UIColor redColor];
[self.view addSubview:animationView];
[UIView animateWithDuration:3 animations:^{
CGRect frame = animationView.frame;
frame.size = CGSizeMake(200, 200);
frame.origin = CGPointMake(20, 20);
animationView.frame = frame;
animationView.backgroundColor = [UIColor blueColor];
}];
- 完成后再变换
[UIView animateWithDuration:4 animations:^{
CGRect frame = animationView.frame;
frame.size = CGSizeMake(200, 200);
frame.origin = CGPointMake(20, 20);
animationView.frame = frame;
animationView.backgroundColor = [UIColor blueColor];
} completion:^(BOOL finished) {
[UIView animateWithDuration:3 animations:^{
animationView.backgroundColor = [UIColor blackColor];
animationView.transform = CGAffineTransformMakeRotation(M_PI_2);
}];
}];
- options
- UIViewAnimationOptionRepeat 重复执行
- UIViewAnimationCurveEaseInOut 缓入缓出
- UIViewAnimationOptionAutoreverse 自动反转
- 弹簧效果
- usingSpringWithDamping 弹簧弹力 0~1 0的时候弹力最大
- initialSpringVelocity 弹簧动画初始速度,取值越大,初始变化越大
[UIView animateWithDuration:3 delay:0 usingSpringWithDamping:0.1 initialSpringVelocity:5 options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat animations:^{
animationView.backgroundColor = [UIColor blackColor];
animationView.transform = CGAffineTransformMakeRotation(M_PI_2);
} completion:nil];
- 关键帧动画
- addKeyframeWithRelativeStartTime 0~1 哪个比例开始
- relativeDuration 0~1 持续多久的比例
[UIView animateKeyframesWithDuration:3 delay:0 options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat animations:^{
// 添加关键帧
[UIView addKeyframeWithRelativeStartTime: 0 relativeDuration:0.3 animations:^{
CGRect frame = animationView.frame;
frame.size = CGSizeMake(200, 200);
frame.origin = CGPointMake(20, 20);
animationView.frame = frame;
}];
[UIView addKeyframeWithRelativeStartTime: 0.3 relativeDuration:0.3 animations:^{
animationView.backgroundColor = [UIColor blueColor];
}];
[UIView addKeyframeWithRelativeStartTime: 0.6 relativeDuration:0.4 animations:^{
animationView.transform = CGAffineTransformMakeRotation(M_PI_2);
}];
} completion:^(BOOL finished) {
}];
- 转场动画,整个view,从某个方向转场成另一个
// transitionFromView时的option 设置多个没什么用
UIViewAnimationOptionTransitionNone
// 从左右翻转
UIViewAnimationOptionTransitionFlipFromLeft
UIViewAnimationOptionTransitionFlipFromRight
// 翻页
UIViewAnimationOptionTransitionCurlUp
UIViewAnimationOptionTransitionCurlDown
// 渐入渐出
UIViewAnimationOptionTransitionCrossDissolve
// 从上下翻转
UIViewAnimationOptionTransitionFlipFromTop
UIViewAnimationOptionTransitionFlipFromBottom
// from - to
[UIView transitionFromView:self.newView toView:self.animationView duration:3 options:UIViewAnimationOptionTransitionFlipFromLeft completion:^(BOOL finished) {
}];
// 单独的animationView的变化
[UIView transitionWithView:self.animationView duration:3 options:UIViewAnimationOptionTransitionFlipFromTop animations:^{
CGRect frame = self.animationView.frame;
frame.size = CGSizeMake(200, 200);
frame.origin = CGPointMake(20, 20);
self.animationView.frame = frame;
} completion:^(BOOL finished) {
}];
核心动画
- basic
// 指定keypath,作为动画指标,也就是layer的属性
CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
basicAnimation.duration = 3;
basicAnimation.repeatCount = 3;
basicAnimation.fromValue = [NSNumber numberWithFloat:0.0];
basicAnimation.toValue = [NSNumber numberWithFloat: M_PI * 0.3];
// 不回到原始位置
basicAnimation.fillMode = kCAFillModeForwards;
basicAnimation.removedOnCompletion = NO;
// 可以根据key进行remove
[animationView.layer addAnimation:basicAnimation forKey:@"demo"];
- keyframe
CAKeyframeAnimation *anim = [CAKeyframeAnimation new];
anim.keyPath = @"position";
NSValue *v1 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
NSValue *v2 = [NSValue valueWithCGPoint:CGPointMake(150, 100)];
NSValue *v3 = [NSValue valueWithCGPoint:CGPointMake(100, 150)];
NSValue *v4 = [NSValue valueWithCGPoint:CGPointMake(150, 150)];
//关键帧数据
anim.values = @[v1,v2,v3,v4];
//时间
anim.duration = 3;
//重复次数
anim.repeatCount = INT_MAX;
[animationView.layer addAnimation:anim forKey:@"demo"];
- 路径动画
CAKeyframeAnimation *anim = [CAKeyframeAnimation new];
anim.keyPath = @"position";
// 路径动画
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:2 * M_PI clockwise:1];
anim.path = path.CGPath;
//时间
anim.duration = 3;
//重复次数
anim.repeatCount = INT_MAX;
[animationView.layer addAnimation:anim forKey:@"demo"];
- 组动画
CAAnimationGroup *group = [CAAnimationGroup new];
//基本动画 自己旋转
CABasicAnimation *anim = [CABasicAnimation new];
anim.keyPath = @"transform.rotation";
anim.byValue = @(2 * M_PI * 10);
//关键帧动画
CAKeyframeAnimation *anim1 = [CAKeyframeAnimation new];
anim1.keyPath = @"position";
//路径动画
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:2 * M_PI clockwise:1];
anim1.path = path.CGPath;
group.animations = @[anim, anim1];
group.duration = 3;
group.repeatCount = INT_MAX;
[animationView.layer addAnimation:group forKey:@"demo"];
Lottie
- 动画库,实现复杂的动画,就是个单单的动画,是额外的
LOTAimationView控件 - 设计师导出json文件,调用接口即可呈现
pod lottie-ios
UIDynamicAnamitor
- 仿真物理学动画
- 类别
- UIGravityBehavior 重力
- UICollisionBehavior 碰撞
- UIAttachmentBehavior 附着
- UISnapBehavior 吸附
- UIPushBehavior 推力
- UIFieldBehavior 场力
- UIDynamicAnamitor
- UIDynamicItem,动力学元素,一个遵守动力学协议的控件
- UIDynamicBehavior,仿真行为,持有UIDynamicItem数组,赋予item这个行为或者唤醒
- UIDynamicAnimator,仿真动画者,执行动画
- 使用
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(20, 0, 30, 30)];
view.layer.cornerRadius = 15;
view.backgroundColor = [UIColor redColor];
[self.view addSubview:view];
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[view]];
gravity.magnitude = 5;
[self.animator addBehavior:gravity];
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[view]];
collision.translatesReferenceBoundsIntoBoundary = YES;
[self.animator addBehavior:collision];