PRTween 是一个用于 iOS 的轻量级程序库。尽管苹果在 UIView 动画和 Core Animation 方面做得非常出色,但有时也会遇到难以解决的问题。如果您需要一种替代方案,PRTween 是一个不错的选择。
[someView layoutSubviews]
PRTween 的目标是尽可能简单,同时不牺牲灵活性。在许多情况下,动画可能非常简单
[PRTween tween:someView property:@"alpha" from:1 to:0 duration:3];
为了促进简单性,PRTween 可以用作您应用程序中大多数动画的直接替换。这意味着在上面的示例中,最终结果与亲自编写 UIView 动画相同。
所以 alpha。真的很厉害。
只需从 /lib/ 中获取 PRTween 和 PRTweenTimingFunction 文件,并将它们添加到项目中。
在核心上,PRTween 分成两个组件。
周期 是表示您计划进行缓动值的时间(开始、当前和结束)三个点的表示。例如,假设您在一秒内将值从 100 缓动到 200。您可以通过创建一个对象来表示这个周期,如下所示
PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:100 endValue:200 duration:3];
组成 PRTween 的第二组件是 操作。操作包含有关如何执行周期的逻辑信息,以及它在执行时会发生什么。您可以将周期视为抽象地表示要执行的工作,而操作则决定它是如何执行的工人。操作可能看起来像这样
PRTweenOperation *operation = [[PRTweenOperation new] autorelease];
operation.period = period;
operation.target = self;
operation.timingFunction = &PRTweenTimingFunctionLinear;
operation.updateSelector = @selector(update:)
上面的代码创建了一个新的操作,在这之前定义的周期上执行缓动。此外,您还告诉操作每次调整值时调用 self
上的 update:
选择器。《code update:《可能看起来像这样
- (void)update:(PRTweenPeriod*)period {
NSLog(@"%f", period.tweenedValue);
}
最后,您需要将操作添加到队列中。
[[PRTween sharedInstance] addTweenOperation:operation]
一旦您这样做了并运行了代码,您就应该能够看到值在 3 秒内从 100 缓动到 200 的控制台跟踪。如果您想将其应用于屏幕上的对象,它可能就是这样简单,将 update:
改为以下内容
// will animate the Y offset of testView from 100 to 200 over the course of 3 seconds
- (void)update:(PRTweenPeriod*)period {
testView.frame = CGRectMake(0, period.tweenedValue, 100, 100);
}
定时函数是 PRTween 的一个关键特性,允许您修改操作如何处理时间周期。例如,尝试将 operation.timingFunction
从 &PRTweenTimingFunctionLinear
改为 &PRTweenTimingFunctionBounceOut
并重新运行您的代码。您应该看到类似动画播放,但这次动画结束时将添加一个弹跳效果。PRTween 包含了一些方便的定时函数
请花点时间在您的应用程序中实验 PRTween 的定时函数,看看您最喜欢哪个。
当在 PRTween 的渐变中省略了 timingFunction
时,将使用默认定时函数。这可以通过 PRTween 上的 defaultTimingFunction
属性访问,尽管您通常通过 [PRTween sharedInstance].defaultTimingFunction
来访问它。
PRTween 最强大的功能之一是能够编写自己的定时函数。由于当前没有文档,请查看 PRTweenTimingFunctions.m 中的示例定时函数。
上面示例中的代码虽然不是很难以处理,但仍可以通过简化来减少需要编写的代码量。对于最常见的情况,PRTween 提供了 缩写 功能以减少需要编写的代码量。
例如,一个简单的 alpha 渐变可以简洁地写成:
[PRTween tween:testView property:@"alpha" from:1 to:0 duration:3];
您还可以直接渐变那些可能不是属性值。假设您正在开发一个滚动位置为 CGFloat
的游戏。
[PRTween tween:&scrollPosition from:0 to:20 duration:3];
PRTween 当前支持以下基本缩写:
// for properties on objects
[PRTween tween:property:from:to:duration:timingFunction:target:completeSelector:]
[PRTween tween:property:from:to:duration:]
// for values
[PRTween tween:from:to:duration:timingFunction:target:completeSelector:]
[PRTween tween:from:to:duration:]
PRTween 也支持块和 lerps 的缩写,下面将解释。
在许多情况下,iOS 中包含的 UIView 或 Core Animation 功能将胜任工作。PRTween 尝试变得智能,将为任何可以通过 UIView 或 Core Animation 触发的属性使用后备。
例如,在 PRTween 中编写以下代码:
[PRTween tween:someView property:@"alpha" from:1 to:0 duration:3];
与不使用 PRTween 编写此代码相同
someView.alpha = 1;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:3];
someView.alpha = 0;
[UIView commitAnimations];
可以使用以下语法在 特定情况 基础上禁用后备:
[PRTween tween:someView property:@"alpha" from:1 to:0 duration:2].override = YES;
或者 全局
[PRTween sharedInstance].useBuiltInAnimationsWhenPossible = NO;
以下 UIView 属性可以适用于 UIView 后备
以下 CALayer 属性可以作为 Core Animation 后备的候选:
对于后备的支持将包括 CGColor、CGPath 和 CATransform3D 属性。
请注意,使用不支持的后备定时函数将使原本适用于后备的动画失效。只有 iOS 伴随内置的曲线才支持后备。它们可以通过以下访问:
如果您针对iOS 4或更高版本,在PRTween中使用时可以利用块。块非常有助于将所有代码放在一个地方。例如,我们可以从上面的示例中删除update:
方法,并在我们的operation
声明中替换以下行
operation.updateBlock = ^(PRTweenPeriod *period) {
testView.frame = CGRectMake(0, period.tweenedValue, 100, 100);
};
您还可以使用块在动画完成后执行代码。
operation.completeBlock = ^{
NSLog("@All done!")
};
块也可以用于简写
// for properties on objects
[PRTween tween:property:from:to:duration:timingFunction:updateBlock:completeBlock]
// for values
[PRTween tween:from:to:duration:timingFunction:updateBlock:completeBlock]
有时您可能需要动画一个复杂的数据值,例如一个CGPoint
。虽然您可以为x
和y
字段分别编写两个tween,但使用线性插值或lerps要简单得多。在PRTween中,通过使用PRTweenLerpPeriod
将lerp与普通tween区分开来。例如,我们可以更改上面的period
声明
PRTweenCGPointLerpPeriod *period = [PRTweenCGPointLerpPeriod periodWithStartCGPoint:CGPointMake(0, 0) endCGPoint:CGPointMake(100, 100) duration:2];
PRTween目前内置了对CGPoint
、CGRect
和CGSize
的lerps,通过PRTweenCGPointLerpPeriod
、PRTweenCGRectLerpPeriod
和PRTweenCGSizeLerpPeriod
。lerps也提供简写形式
// for CGPoint
[PRTweenCGPointLerp lerp:property:from:to:duration:timingFunction:target:completeSelector:]
[PRTweenCGPointLerp lerp:property:from:to:duration:]
// for CGSize
[PRTweenCGSizeLerp lerp:property:from:to:duration:timingFunction:target:completeSelector:]
[PRTweenCGSizeLerp lerp:property:from:to:duration:]
// for CGRect
[PRTweenCGRectLerp lerp:property:from:to:duration:timingFunction:target:completeSelector:]
[PRTweenCGRectLerp lerp:property:from:to:duration:]
// blocks for iOS 4 or greater
[PRTweenCGPointLerp lerp:property:from:to:duration:timingFunction:target:updateBlock:completeBlock:]
[PRTweenCGSizeLerp lerp:property:from:to:duration:timingFunction:target:updateBlock:completeBlock:]
[PRTweenCGRectLerp lerp:property:from:to:duration:timingFunction:target:updateBlock:completeBlock:]
PRTween最强大的功能之一就是能够使用自定义线性插值。通常,继承自PRTweenLerpPeriod
并实现<PRTweenLerpPeriod>
协议的类可以用作自定义线性插值。这使得我们能够轻松地动画任何复杂数值。文档将提供,但到目前为止,您可以查看PRTweenCGPointLerpPeriod
背后的代码以获取更多详细信息。
API文档即将推出。在此之前,您鼓励深入了解代码以获取关于高级功能的信息。PRTween非常简洁,您可能在一两个小时就能弄清楚所有内容。
PRTween非常新,所以目前还没有很多规则。
惊喜!这是BSD许可证。
Copyright (c) 2011, Dominik Hofmann All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.