PMTween 是一个优雅且灵活的 Objective-C 调用库,目前支持 iOS 和 tvOS 平台。它提供了合理的默认功能,可以抽象掉大部分繁琐的工作,让您能够专注于动画和其他调用任务。但 PMTween 也便于您根据自己的需求进行修改,无论是自定义调用类、支持自定义对象类型还是新的缓动方程。
如果您正在用 Swift 编程,可以尝试 MotionMachine,它是基于 PMTween 开发的,但带有许多改进以及针对该语言定制的 API。
PMTween 中的所有基本调用类都采用 PMTweening 协议,并且可以将这些类中的任何一种添加到 PMTweenGroup 或 PMTweenSequence 实例中。它们可以嵌套到您想要的任何深度,PMTweenGroup 和 PMTweenSequence 会尊重它们的子项的调用属性。如果您想使用您自己的自定义调用类,只需采用该协议。但是,PMTweenUnit 的模块化如此之好,在大多数情况下,您只需要用您自己的实现替换您需要的部分。
换句话说,这段代码
PMTweenEasingBlock easing = [PMTweenEasingCubic easingInOut];
PMTweenEasingBlock easing2 = [PMTweenEasingCircular easingInOut];
PMTweenUnit *tween1 = [[PMTweenUnit alloc] initWithObject:self.tweenView propertyKeyPath:@"frame.origin.x" startingValue:self.tweenView.frame.origin.x endingValue:110 duration:1.5 options:PMTweenOptionNone easingBlock:easing];
PMTweenUnit *tween2 = [[PMTweenUnit alloc] initWithObject:self.tweenView propertyKeyPath:@"backgroundColor.blue" startingValue:0.30 endingValue:1.0 duration:1.2 options:PMTweenOptionNone easingBlock:easing];
PMTweenUnit *tween3 = [[PMTweenUnit alloc] initWithObject:self.tweenView propertyKeyPath:@"frame.size.width" startingValue:self.tweenView.frame.size.width endingValue:120 duration:0.9 options:PMTweenOptionNone easingBlock:easing2];
PMTweenUnit *tween4 = [[PMTweenUnit alloc] initWithObject:self.tweenView propertyKeyPath:@"frame.origin.y" startingValue:self.tweenView.frame.origin.y endingValue:100 duration:1.0 options:PMTweenOptionNone easingBlock:easing];
PMTweenGroup *group = [[PMTweenGroup alloc] initWithTweens:@[tween1, tween2] options:PMTweenOptionNone];
PMTweenSequence *sequence = [[PMTweenSequence alloc] initWithSequenceSteps:@[group, tween3, tween4] options:PMTweenOptionReverse|PMTweenOptionRepeat];
sequence.reversingMode = PMTweenSequenceReversingContiguous;
[sequence startTween];
生成这个动画
1.2.0 版本中增加了对 PMTweenUnit 中增量动画的支持。增量动画可以让多个调用产生复合效果,而不是像它们更新同一个属性时那样互相覆盖。自 iOS 8 开始,增量动画已是调用动作的默认行为,非常适合制作流畅且响应灵敏的用户界面动画。当然,在 PMTweenUnit 中,您不仅限于调用 UIView 属性,因此增量调用可以应用于任何兼容的属性。只需将任何 PMTweenUnit 实例的 additive
设置为 YES,您希望将其调用更新进行组合的即可。请参阅文档和更新的 示例项目 获取更多信息以及使用此模式时应注意的事项。为此概念更清晰地感谢 Andy Matuschak 和 Kevin Doughty。
在 1.1.0 版本中添加了PMTweenPhysicsUnit,它提供了基于物理的动态缓动。(感谢Pop库的灵感!)由于它采用了PMTweening协议,您可以按需将其与其他PMTween类组合使用。
有关更多信息,请参阅包含的PMTween使用示例,并查看文档。
如果您使用 CocoaPods
pod "PMTween", "~> 1.3.0"
或添加 Classes 目录到您的项目中。
这是最基本类型的缓动,它直接对任意数据结构进行缓动。PMTweenUnit是PMTween中的主力缓动类,它处理所有实际的属性更新。注意,传递了nil作为easingBlock,这意味着它将使用默认的PMTweenEasingLinear缓动类型。
#import <PMTween/PMTween.h>
PMTweenUnit *tween = [[PMTweenUnit alloc] initWithProperty:@(0) startingValue:0 endingValue:100 duration:1.0 options:PMTweenOptionNone easingBlock:nil];
[tween startTween];
这是另一个基本示例。注意,这次我们传入了选项掩码到options参数中,这将使它反向缓动回到起始值(在击中endingValue之后),并且重复它的缓动多个周期。在这种情况下,它会重复总的缓动操作(前进和后退)。
我们还定义了一个完整块,当缓动完成所有重复周期时将被调用。注意,块参数指定了NSObject<PMTweening>
,而不是PMTweenUnit。它表示这可能是任何符合PMTweening协议的对象。如果您想访问您的缓动类中未指定由PMTweening协议定义的特定属性,您需要先将'tween'对象强制转换为您的特定类类型。
PMTweenUnit *tween = [[PMTweenUnit alloc] initWithProperty:@(0) startingValue:0 endingValue:100 duration:1.0 options:PMTweenOptionRepeat|PMTweenOptionReverse easingBlock:nil];
tween.completeBlock = ^void(NSObject<PMTweening> *tween) {
NSLog(@"tween complete!");
};
tween.numberOfRepeats = 2;
[tween startTween];
更常见的需要是对对象属性进行缓动,例如UIView的x位置。检查下面的示例。注意,此方法需要一个键。这是从对象到您想要缓动属性的对象层次结构。即使'x'值不能直接设置在frame的origin上,但PMTween足够智能,可以为您处理这一更新。PMTween处理大多数常见的UIKit属性;请参阅文档或代码,以了解它确切支持的内容,并且告诉我它的缺失之处。
此外,我们这次定义了一个easingBlock。您也可以通过设置PMTweenUnit的reverseEasingBlock属性来为反转缓动分配不同的缓动块。PMTween包括了所有标准的Robert Penner缓动类型,但您也可以轻松地使用您自己的缓动类。也许您想通过对普林噪声滤波器或用陀螺仪数据偏移值来修改缓动。谁知道呢?我不知道。这正是为什么PMTween使您能够轻松地做自己的事情。
PMTweenEasingBlock easing = [PMTweenEasingCubic easingInOut];
PMTweenUnit *tween = [[PMTweenUnit alloc] initWithObject:self.tweenView propertyKeyPath:@"frame.origin.x" startingValue:self.tweenView.frame.origin.x endingValue:200 duration:1.0 options:PMTweenOptionNone easingBlock:easing];
[tween startTween];
PMTweenGroup管理多个实例。这对于控制和同步多个缓动对象很方便。当然,您可以在其他组中也有组。
请注意,在本示例中,一个tempo对象被设置为PMTweenGroup。它提供了一个tempo,换句话说,是tween更新其缓动计算的速度率。除非您想使用自己的自定义tempo对象,否则无需设置此功能——所有PMTween tweening类默认情况下都是内部创建自己的tempo对象。
PMTweenEasingBlock easing = [PMTweenEasingCubic easingInOut];
PMTweenUnit *tween = [[PMTweenUnit alloc] initWithObject:self.tweenView propertyKeyPath:@"frame.size.width" startingValue:self.tweenView.frame.size.width endingValue:200 duration:1.0 options:PMTweenOptionNone easingBlock:easing];
PMTweenUnit *tween2 = [[PMTweenUnit alloc] initWithObject:self.tweenView propertyKeyPath:@"frame.size.height" startingValue:self.tweenView.frame.size.height endingValue:300 duration:2.0 options:PMTweenOptionNone easingBlock:easing];
PMTweenGroup *group = [[PMTweenGroup alloc] initWithTweens:@[tween, tween2] options:PMTweenOptionReverse];
[group setTempo:[PMTweenCATempo tempo]];
[group startTween];
PMTweenSequence按顺序播放一系列tween。将tween链接在一起非常容易。这是一个强大的类,您可以按顺序播放任何组合的PMTweenUnits、PMTweenGroups或其他PMTweenSequence类,以及您自己的自定义tween类。这里的tween贯穿始终。请注意,我们传入一个序列步骤数组——它将按照该顺序播放序列。
当PMTweenSequence设置为反转时,默认情况下,在反转时会作为离散元素播放(也就是说,每个子tween将只直接向前播放,但在反向顺序中)。但是,通过将序列的reversingMode设置为PMTweenSequenceReversingContiguous,可以设置整个序列连续反转,就像是一个连续的tween一样。这对复杂动画来说真是太棒了。
PMTweenEasingBlock easing = [PMTweenEasingCubic easingInOut];
PMTweenUnit *tween = [[PMTweenUnit alloc] initWithObject:self.tweenView propertyKeyPath:@"frame.origin.x" startingValue:self.tweenView.frame.origin.x endingValue:200 duration:1.0 options:PMTweenOptionNone easingBlock:easing];
PMTweenUnit *tween2 = [[PMTweenUnit alloc] initWithObject:self.tweenView propertyKeyPath:@"frame.size.height" startingValue:self.tweenView.frame.size.height endingValue:300 duration:2.0 options:PMTweenOptionNone easingBlock:easing];
PMTweenSequence *sequence = [[PMTweenSequence alloc] initWithSequenceSteps:@[tween1, tween2] options:PMTweenOptionReverse];
[sequence startTween];
Tween类 | |
---|---|
PMTweenUnit | PMTweenUnit处理对NSValue的单个tween操作,在指定的起始值和结束值之间进行插值。 |
PMTweenPhysicsUnit | PMTweenPhysicsUnit处理对NSValue的单个基于物理的tween操作,使用物理系统通过衰减速度更新值。 |
PMTweenGroup | PMTweenGroup处理一个或多个遵循PMTweening协议的对象的tween,这些对象可以是PMTweenUnit的实例或其他自定义类。当您想轻松同步多个tween的操作时,PMTweenGroup类是一个很好的解决方案。 |
PMTweenSequence | PMTweenSequence允许符合PMTweening协议的对象在一个连续的tween步骤中链在一起。 |
节奏类 | |
PMTweenCATempo | PMTweenCATempo是PMTweenTempo的具体子类,并使用CADisplayLink对象发送与显示刷新率同步的tempo更新。 |
PMTweenBeat | PMTweenBeat从PMTweenTempo对象向多个采用PMTweening协议的对象广播更新。这允许您对所有tween对象使用单个tempo对象,避免了在tween多个对象时性能的影响。 |
缓动类型 | |
PMTweenEasingLinear | 提供线性缓动方程。 |
PMTweenEasingQuadratic | 提供二次缓动方程。 |
PMTweenEasingQuartic | 提供四次缓动方程。 |
PMTweenEasingQuintic | 提供五次缓动方程。 |
PMTweenEasingCubic | 提供三次缓动方程。 |
PMTweenEasingSine | 提供基于正弦的缓动方程。 |
PMTweenEasingCircular | 提供圆周缓动方程。 |
PMTweenEasingElastic | 提供弹性缓动方程。 |
PMTweenEasingExpo | 提供指数缓动方程。 |
PMTweenEasingBack | 提供回弹缓动方程。 |
PMTweenEasingBounce | 提供类似于弹跳球的逐渐减小峰值值的缓动方程。 |
PMTween使用Specta/Expecta进行测试。您可以通过在测试目录中运行'pod install'来使用CocoaPods安装测试依赖项。
PMTween由Brett Walker在Poet & Mountain创建。
PMTween 采用 MIT 许可证。如果您在您的应用中使用 PMTween,我很乐意了解!