进行封装,以此来降低入侵性,实现低耦合的要求:
#define LXDMAXDURATION 1.2
#define LXDMINDURATION .2
#define LXDMULTIPLED .25
@interface UIView (LXDFadeAnimation)
/*!
* @brief 视图是否隐藏
*/
@property (nonatomic, assign, readonly) BOOL isFade;
/*!
* @brief 是否处在动画中
*/
@property (nonatomic, assign, readonly) BOOL isFading;
/*!
* @brief 垂直方块个数。默认为3
*/
@property (nonatomic, assign) NSInteger verticalCount;
/*!
* @brief 水平方块个数。默认为18
*/
@property (nonatomic, assign) NSInteger horizontalCount;
/*!
* @brief 方块动画之间的间隔0.2~1.2。默认0.7
*/
@property (nonatomic, assign) NSTimeInterval intervalDuration;
/*!
* @brief 每个方块隐藏的动画时间0.05~0.3,最多为动画时长的25%。默认为0.175
*/
@property (nonatomic, assign) NSTimeInterval fadeAnimationDuration;
- (void)configurateWithVerticalCount: (NSInteger)verticalCount horizontalCount: (NSInteger)horizontalCount interval: (NSTimeInterval)interval duration: (NSTimeInterval)duration;
- (void)reverseWithComplete: (void(^)(void))complete;
- (void)animateFadeWithComplete: (void(^)(void))complete;
- (void)reverseWithoutAnimate;
@end
在iOS中,在category中声明的所有属性编译器都不会自动绑定getter和setter方法,这意味着我们需要重写这两种方法,而且还不能使用下划线+变量名的方式直接访问变量。因此我们需要导入objc/runtime.h文件使用动态时提供的objc_associateObject机制来为视图动态增加属性:
- (BOOL)isFade
{
return [objc_getAssociatedObject(self, kIsFadeKey) boolValue];
}
// other getAssociatedObject method
- (void)setIsFade: (BOOL)isFade
{
objc_setAssociatedObject(self, kIsFadeKey, @(isFade), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
// other setAssociatedObject method
有了碎片化隐藏视图的动画,同样需要一个还原的动画效果:
NSInteger fadeCount = self.verticalCount * self.horizontalCount;
for (NSInteger idx = fadeCount - 1; idx >= 0; idx--) {
UIView * subview = [self.maskView viewWithTag: [self subViewTag: idx]];
[UIView animateWithDuration: self.fadeAnimationDuration delay: self.intervalDuration * (fadeCount - 1 - idx) options: UIViewAnimationOptionCurveLinear animations: ^{
subview.alpha = 1;
} completion: nil];
}
现在我们还要考虑一个问题:假设用户点击某张图片的时候就根据视图是否隐藏状态来开始隐藏/显示的动画,当用户多次点击的时候,我们应该判断是否已经处在动画状态,如果是,那么不继续执行动画代码。另外,在动画开始之前,我们需要把标识动画状态的isFading设为YES,但是由于每个方块隐藏都存在一个动画,动画的结束时间应该怎么判断呢?已知fadeView的个数是










