这是我参与「第四届青训营」笔记创作活动的的第十九天。本篇文章将会简单介绍iOS的交互、手势与动画编程。
可以首先看一看对于iOS交互、手势和动画的大体关系:
一、交互与手势
手势识别器
手势识别器用来解释触摸以确定它们是否对应于特定手势,诸如滑动,捏合或旋转,如果识别他们特定的手势,他们发送动作消息到目标对象。目标对象通常是视图的控制器,它响应手势,如下图所示:
引用:www.jianshu.com/p/a8c04c702…
UIGestureRecognizer
iOS 系统提供了一些常用的手势(UIGestureRecognizer 的子类),开发者可以直接使用他们进行手势操作:
UIPanGestureRecognizer(平移或者拖动)
UIPinchGestureRecognizer(缩放)
UIRotationGestureRecognizer(旋转)
UITapGestureRecognizer(点击)
UILongPressGestureRecognizer(长按)
UISwipeGestureRecognizer(滑动)
引用:www.jianshu.com/p/a8c04c702…
手势状态
typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
UIGestureRecognizerStatePossible, // 尚未识别是何种手势操作(但可能已经触发了触摸事件),默认状态
UIGestureRecognizerStateBegan, // 手势已经开始,此时已经被识别,但是这个过程中可能发生变化,手势操作尚未完成
UIGestureRecognizerStateChanged, // 手势状态发生转变
UIGestureRecognizerStateEnded, // 手势识别操作完成(此时已经松开手指)
UIGestureRecognizerStateCancelled, // 手势被取消,恢复到默认状态
UIGestureRecognizerStateFailed, // 手势识别失败,恢复到默认状态
UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded // 手势识别完成,同UIGestureRecognizerStateEnded
};
事件响应机制
UITouch介绍
typedef NS_ENUM(NSInteger, UITouchPhase) {
UITouchPhaseBegan, // 开始触摸
UITouchPhaseMoved, // 触摸移动
UITouchPhaseStationary, // 触摸没有移动
UITouchPhaseEnded, //触摸结束
UITouchPhaseCancelled, //取消触摸
};
@interface UITouch : NSObject
//属性
//时间戳记录了触摸事件产生或变化时的时间,单位是秒
@property(nonatomic,readonly) NSTimeInterval timestamp;
//当前触摸事件在一个周期中所处的状态
@property(nonatomic,readonly) UITouchPhase phase;
//表示短时间内点按屏幕的次数
@property(nonatomic,readonly) NSUInteger tapCount;
//触摸的主半径
@property(nonatomic,readonly) CGFloat majorRadius;
//触摸的主半径的公差
@property(nonatomic,readonly) CGFloat majorRadiusTolerance;
//触摸产生时所处的窗口。由于窗口可能发生变化,当前所在的窗口不一定是最开始的窗口
@property(nonatomic,readonly,retain) UIWindow *window;
//触摸产生时所处的视图。由于视图可能发生变化,当前视图也不一定时最初的视图
@property(nonatomic,readonly,retain) UIView *view;
//触摸手势数组
@property(nonatomic,readonly,copy) NSArray *gestureRecognizers;
//方法
//返回当前触摸点的位置
- (CGPoint)locationInView:(UIView *)view;
//返回上一个触摸点的位置
- (CGPoint)previousLocationInView:(UIView *)view;
@end
UIEvent介绍
//属性
//获取事件类型
typedef NS_ENUM(NSInteger, UIEventType) {
UIEventTypeTouches, // 触摸事件
UIEventTypeMotion, // 加速事件
UIEventTypeRemoteControl, // 远程控制事件
UIEventTypePresses, //按压事件
};
//输入事件不同类型的一些具体事件枚举
@property(nonatomic,readonly) UIEventSubtype subtype;
UIEventSubtype 枚举:
// 不包含任何子事件类型
UIEventSubtypeNone = 0,
// 摇晃事件(从iOS3.0开始支持此事件)
UIEventSubtypeMotionShake = 1,
//远程控制子事件类型(从iOS4.0开始支持远程控制事件)
//播放事件【操作:停止状态下,按耳机线控中间按钮一下】
UIEventSubtypeRemoteControlPlay = 100,
//暂停事件
UIEventSubtypeRemoteControlPause = 101,
//停止事件
UIEventSubtypeRemoteControlStop = 102,
//播放或暂停切换【操作:播放或暂停状态下,按耳机线控中间按钮一下】
UIEventSubtypeRemoteControlTogglePlayPause = 103,
//下一曲【操作:按耳机线控中间按钮两下】
UIEventSubtypeRemoteControlNextTrack = 104,
//上一曲【操作:按耳机线控中间按钮三下】
UIEventSubtypeRemoteControlPreviousTrack = 105,
//快退开始【操作:按耳机线控中间按钮三下不要松开】
UIEventSubtypeRemoteControlBeginSeekingBackward = 106,
//快退停止【操作:按耳机线控中间按钮三下到了快退的位置松开】
UIEventSubtypeRemoteControlEndSeekingBackward = 107,
//快进开始【操作:按耳机线控中间按钮两下不要松开】
UIEventSubtypeRemoteControlBeginSeekingForward = 108,
//快进停止【操作:按耳机线控中间按钮两下到了快进的位置松开】
UIEventSubtypeRemoteControlEndSeekingForward = 109
//类
@interface UIEvent : NSObject
//属性
@property(nonatomic,readonly) UIEventType type ; //事件类型
@property(nonatomic,readonly) UIEventSubtype subtype ; //同一事件类型的具体事件
@property(nonatomic,readonly) NSTimeInterval timestamp; //事件触发时间间隔
//方法
//所有触摸点
- (NSSet *)allTouches;
//窗体上的触摸点
- (NSSet *)touchesForWindow:(UIWindow *)window;
//视图上的触摸点
- (NSSet *)touchesForView:(UIView *)view;
//手势触摸点
- (NSSet *)touchesForGestureRecognizer:(UIGestureRecognizer *)gesture;
@end
UIResponder
//手指触碰屏幕,触摸开始
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
//手指在屏幕上移动
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
//手指离开屏幕,触摸结束
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
//触摸结束前,某个系统事件中断了触摸,例如电话呼入
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
事件派发
二、动画编程
UIView动画
UIView动画实质上是对Core Animation的封装,提供简洁的动画接口。
UIView动画可以设置的动画属性有:
- 大小变化(frame)
- 拉伸变化(bounds)
- 中心位置(center)
- 旋转(transform)
- 透明度(alpha)
- 背景颜色(backgroundColor)
- 拉伸内容(contentStretch)
UI类方法动画:
- block动画
[UIView animateWithDuration:(NSTimeInterval) //动画持续时间
animations:^{
//执行的动画
}];
[UIView animateWithDuration:(NSTimeInterval) //动画持续时间
animations:^{
//执行的动画
} completion:^(BOOL finished) {
//动画执行提交后的操作
}];
[UIView animateWithDuration:(NSTimeInterval) //动画持续时间
delay:(NSTimeInterval) //动画延迟执行的时间
options:(UIViewAnimationOptions) //动画的过渡效果
animations:^{
//执行的动画
} completion:^(BOOL finished) {
//动画执行提交后的操作
}];
UIViewAnimationOptions的枚举值:
UIViewAnimationOptionLayoutSubviews //进行动画时布局子控件
UIViewAnimationOptionAllowUserInteraction //进行动画时允许用户交互
UIViewAnimationOptionBeginFromCurrentState //从当前状态开始动画
UIViewAnimationOptionRepeat //无限重复执行动画
UIViewAnimationOptionAutoreverse //执行动画回路
UIViewAnimationOptionOverrideInheritedDuration //忽略嵌套动画的执行时间设置
UIViewAnimationOptionOverrideInheritedCurve //忽略嵌套动画的曲线设置
UIViewAnimationOptionAllowAnimatedContent //转场:进行动画时重绘视图
UIViewAnimationOptionShowHideTransitionViews //转场:移除(添加和移除图层的)动画效果
UIViewAnimationOptionOverrideInheritedOptions //不继承父动画设置
UIViewAnimationOptionCurveEaseInOut //时间曲线,慢进慢出(默认值)
UIViewAnimationOptionCurveEaseIn //时间曲线,慢进
UIViewAnimationOptionCurveEaseOut //时间曲线,慢出
UIViewAnimationOptionCurveLinear //时间曲线,匀速
UIViewAnimationOptionTransitionNone //转场,不使用动画
UIViewAnimationOptionTransitionFlipFromLeft //转场,从左向右旋转翻页
UIViewAnimationOptionTransitionFlipFromRight //转场,从右向左旋转翻页
UIViewAnimationOptionTransitionCurlUp //转场,下往上卷曲翻页
UIViewAnimationOptionTransitionCurlDown //转场,从上往下卷曲翻页
UIViewAnimationOptionTransitionCrossDissolve //转场,交叉消失和出现
UIViewAnimationOptionTransitionFlipFromTop //转场,从上向下旋转翻页
UIViewAnimationOptionTransitionFlipFromBottom //转场,从下向上旋转翻页
- 弹簧(spring)动画
self.redView.alpha = 0.0;
[UIView animateWithDuration:(NSTimeInterval)//动画持续时间
delay:(NSTimeInterval)//动画延迟执行的时间
usingSpringWithDamping:(CGFloat)//震动效果,范围0~1,数值越小震动效果越明显
initialSpringVelocity:(CGFloat)//初始速度,数值越大初始速度越快
options:(UIViewAnimationOptions)//动画的过渡效果
animations:^{
//执行的动画
self.redView.alpha = 1.0;
self.redView.frame = CGRectMake(200, 350, 140, 140);
}
completion:^(BOOL finished) {
//动画执行提交后的操作
}];
- 关键帧(keyframes)动画
IOS7.0后新增了关键帧动画,支持属性关键帧,不支持路径关键帧
[UIView animateKeyframesWithDuration:(NSTimeInterval)//动画持续时间
delay:(NSTimeInterval)//动画延迟执行的时间
options:(UIViewKeyframeAnimationOptions)//动画的过渡效果
animations:^{
//执行的关键帧动画
}
completion:^(BOOL finished) {
//动画执行提交后的操作
}];
UIViewAnimationOptionLayoutSubviews //进行动画时布局子控件
UIViewAnimationOptionAllowUserInteraction //进行动画时允许用户交互
UIViewAnimationOptionBeginFromCurrentState //从当前状态开始动画
UIViewAnimationOptionRepeat //无限重复执行动画
UIViewAnimationOptionAutoreverse //执行动画回路
UIViewAnimationOptionOverrideInheritedDuration //忽略嵌套动画的执行时间设置
UIViewAnimationOptionOverrideInheritedOptions //不继承父动画设置
UIViewKeyframeAnimationOptionCalculationModeLinear //运算模式 :连续
UIViewKeyframeAnimationOptionCalculationModeDiscrete //运算模式 :离散
UIViewKeyframeAnimationOptionCalculationModePaced //运算模式 :均匀执行
UIViewKeyframeAnimationOptionCalculationModeCubic //运算模式 :平滑
UIViewKeyframeAnimationOptionCalculationModeCubicPaced //运算模式 :平滑均匀
//增加关键帧方法
[UIView addKeyframeWithRelativeStartTime:(double)//动画开始的时间(占总时间的比例)
relativeDuration:(double) //动画持续时间(占总时间的比例)
animations:^{
//执行的动画
}];
- 转场动画
[UIView transitionFromView:(nonnull UIView *) toView:(nonnull UIView *) duration:(NSTimeInterval) options:(UIViewAnimationOptions) completion:^(BOOL finished) {
//动画执行提交后的操作
}];
详细内容可以阅读:www.jianshu.com/p/5abc038e4…
核心动画
CAAnimation(抽象类)
继承关系:
核心动画类中可以直接使用的类有:
- CABasicAnimation 基本动画
- CAKeyframeAnimation 关键帧动画
- CATransition 转场动画
- CAAnimationGroup 动画组
- CASpringAnimation 弹簧动画
Lottie动画
Lottie动画是一种跨平台复杂动画的实现,支持iOS、android、web、react native等。通过JSON来描述动画过程。
创建lottie动画:
LOTAnimationView *lottieView = [LOTAnimationView animationNamed:@"fire"];
更多详细内容可以阅读:juejin.cn/post/684490…
Reference
《iOS 交互、手势与动画编程》juejin.cn/post/712344…
《iOS手势识别器》www.jianshu.com/p/a8c04c702…
《iOS:触摸控件UITouch、事件类UIEvent》developer.aliyun.com/article/366…
《iOS动画篇:UIView动画》www.jianshu.com/p/5abc038e4…
《iOS:核心动画的详解介绍:CAAnimation(抽象类)及其子类》developer.aliyun.com/article/366…
《Lottie - 轻松实现复杂的动画效果》juejin.cn/post/684490…