前沿
项目因为越做越大,所以为了配合模块化开发的时候,想到了如何进行展示,想起来支付宝和微信的present方式,就想到了如何操作了。
正文
想要实现不一般又炫酷的present过渡动画,则必须使用自定义动画了,主要就是UIViewControllerAnimatedTransitioning
这个协议中进行具体的动画操作。
网上也看过其他人写的,虽然确实挺花俏的,但是真正导入项目的时候有些不可用,最典型的问题就是影响了原有的代码,还有就是只支持一次性展示效果,达不到多层次效果,比如present一个controllerA之后,再从controllerA present到controllerB。为了完善一下,特地整理了一下项目中的分享给大家,demo地址
当然,为这个只是针对present模态展示的,就和支付宝的效果是一样的。
总共用到的效果有定义为四种
typedef NS_ENUM(NSInteger,BDTransformType){
/*push动画*/
BDTransformPush,
/**pop动画*/
BDTransformPop,
/**present model动画*/
BDTransformPresent,
/**present dismiss动画*/
BDTransformDismiss,
};
具体步骤
1、在BDTransformPresent
的时候,原来的整个背景向下缩放动画,目标页面从底部弹出,
2、在BDTransformDismiss
的时候,与BDTransformPresent
对应,
如果是左滑手势,,
3、在BDTransformPush
的时候,页面和正常的push 类似
4、在BDTransformPop
与push对应
组成部分
1、控制器分类,如果想要使用这个效果,则直接bd_present即可
@interface UIViewController (PresentAnimation)
///是否存在这个present自定义动画,如果不是调用bd_present的方式则为no
@property (nonatomic, assign,readonly)BOOL presentAnimation;
///默认为nil ,如果调用了bd_present后,则被presnent的控制器则存在这个Key值,方便在delloc的时候将animator销毁
@property (nonatomic,copy,readonly)NSString *presentKey;
/**
特殊present样式,
*/
- (void)bd_presentViewController:(UIViewController*)controller animated:(BOOL)animated completion:(void (^)(void))completion;
@end
2、对象管理记具体实施者
/**
每个present的操作对应的代理都是一对一的,所以只能针对单个对象
*/
@interface BDPresentAnimator : NSObject<UIViewControllerTransitioningDelegate>
@property (nonatomic,weak)UIViewController *controller;
@end
NS_ASSUME_NONNULL_END
/**
专门管理复杂保存与删除代理,动画保持的效果必须在BDPresentAnimator生命周期内
*/
@interface BDPresentAnimatorManager : NSObject
+ (instancetype)manager;
- (void)addAnimaor:(BDPresentAnimator*)animator withKey:(NSString*)key;
/**需要在控制器销毁的时候手动remove动画对象*/
- (void)removeAnimatorWithKey:(NSString*)key;
/**需要在控制器销毁的时候手动remove动画对象*/
- (void)removeAnimatorWithController:(UIViewController*)controller;
@end
3、具体动画实现方式
/**
针对模块化设计方案
这个暂时只针对present类型的,因为将这些操作可以只在被present内部处理,而无需在每次都在外部处理,这样方面
代码设计本应如此
*/
@interface BDPresentAnimatorAction : NSObject<UIViewControllerAnimatedTransitioning>
/**
动画样式
*/
@property (nonatomic,assign)BDTransformType transformType;
@end
/**
只贴了一种实现
*/
- (void)presentAnimationWithTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
toView.frame = transitionContext.containerView.bounds;
[transitionContext.containerView addSubview:toView];
CGFloat width = toView.bounds.size.width;
CGFloat height = toView.bounds.size.height;
toView.frame = CGRectMake(0, height, width, height);
fromView.layer.zPosition = -1;
CATransform3D scale = CATransform3DIdentity;
scale = CATransform3DScale(scale, [UIScreen mainScreen].bounds.size.height == 812.0f?0.94:0.95, [UIScreen mainScreen].bounds.size.height == 812.0f?0.96:0.97, 1);
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
fromView.layer.transform = scale;
toView.frame = CGRectMake(0, 0, width, height);
} completion:^(BOOL finished) {
[transitionContext completeTransition:!transitionContext.transitionWasCancelled];
fromView.layer.zPosition = 0;
fromView.layer.transform = CATransform3DIdentity;
}];
}
具体使用
第一步:
UIViewController *controller = [[NSClassFromString(@"BDStoreTabBarController") alloc]init];
[self.navigationController bd_presentViewController:controller animated:YES completion:nil];
第二步:
在BDStoreTabBarController页面delloc的时候
-(void)dealloc
{
[[BDPresentAnimatorManager manager] removeAnimatorWithController:self];
或者
[self removePresentAnimator];
}
![](https://img.haomeiwen.com/i6476736/74fda1921c6f081c.gif)
后续将考虑弄一个bool值,设置一下页面是否支持左滑页面,如果你有点子,可以留言哈,大家一起学习。
网友评论