【发布时间】:2015-07-16 19:08:14
【问题描述】:
所以我已经开始创建自定义推送/弹出转换,并且第一次推送转换一切正常,但是当我尝试推送另一个视图控制器时,我根本没有动画。
Here is a sample project with the code
大量代码传入:
这是我的 UINavigationControllerDelegate 类:
@interface CKMNavigationControllerDelegate : NSObject <UINavigationControllerDelegate>
- (instancetype)initWithForwardTransitionObject:(id<UIViewControllerAnimatedTransitioning>)inForwardTransitionObject popTransitionObject:(id<UIViewControllerAnimatedTransitioning>)inBackTransitionObject;
@property(nonatomic, strong) id<UIViewControllerAnimatedTransitioning> forwardTransitionObject;
@property(nonatomic, strong) id<UIViewControllerAnimatedTransitioning> backTransitionObject;
@end
@implementation CKMNavigationControllerDelegate
- (instancetype)initWithForwardTransitionObject:(id<UIViewControllerAnimatedTransitioning>)inForwardTransitionObject popTransitionObject:(id<UIViewControllerAnimatedTransitioning>)inBackTransitionObject
{
NSAssert( [inForwardTransitionObject conformsToProtocol:@protocol(UIViewControllerAnimatedTransitioning)], @"inForwardTransitionObject does not conform to protocol UIViewControllerAnimatedTransitioning" );
NSAssert( [inBackTransitionObject conformsToProtocol:@protocol(UIViewControllerAnimatedTransitioning)], @"inBackTransitionObject does not conform to protocol UIViewControllerAnimatedTransitioning" );
self = [super init];
if( !self ) return nil;
_forwardTransitionObject = inForwardTransitionObject;
_backTransitionObject = inBackTransitionObject;
return self;
}
- (void)setForwardTransitionObject:(id<UIViewControllerAnimatedTransitioning>)inForwardTransitionObject
{
NSAssert( [inForwardTransitionObject conformsToProtocol:@protocol(UIViewControllerAnimatedTransitioning)], @"inForwardTransitionObject does not conform to protocol UIViewControllerAnimatedTransitioning" );
_forwardTransitionObject = inForwardTransitionObject;
}
- (void)setBackTransitionObject:(id<UIViewControllerAnimatedTransitioning>)inBackTransitionObject
{
NSAssert( [inBackTransitionObject conformsToProtocol:@protocol(UIViewControllerAnimatedTransitioning)], @"inBackTransitionObject does not conform to protocol UIViewControllerAnimatedTransitioning" );
_backTransitionObject = inBackTransitionObject;
}
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)inNavigationController animationControllerForOperation:(UINavigationControllerOperation)inOperation fromViewController:(UIViewController *)inFroViewController toViewController:(UIViewController *)inToViewController
{
return inOperation == UINavigationControllerOperationPush ? self.forwardTransitionObject : self.backTransitionObject;
}
我的类为推送转换实现 UIViewControllerAnimatedTransitioning:
@interface CKMForwardTransitionObject : NSObject <UIViewControllerAnimatedTransitioning>
@end
@implementation CKMForwardTransitionObject
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
NSAssert([toViewController conformsToProtocol:@protocol(CKMTransitionAnimatable)], @"toViewController does not conform to CKMTransitionAnimatable");
NSAssert([fromViewController conformsToProtocol:@protocol(CKMTransitionAnimatable)], @"fromViewController does not conform to CKMTransitionAnimatable");
id <CKMTransitionAnimatable> fromAnimationSource = (id <CKMTransitionAnimatable>)fromViewController;
id <CKMTransitionAnimatable> toAnimationSource = (id <CKMTransitionAnimatable>)toViewController;
CGFloat duration = [fromAnimationSource transitionOutDuration] + [toAnimationSource transitionInDuration];
return duration;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
NSAssert([toViewController conformsToProtocol:@protocol(CKMTransitionAnimatable)], @"toViewController does not conform to CKMTransitionAnimatable");
NSAssert([fromViewController conformsToProtocol:@protocol(CKMTransitionAnimatable)], @"fromViewController does not conform to CKMTransitionAnimatable");
UIView *containerView = [transitionContext containerView];
[containerView addSubview:toViewController.view];
[containerView addSubview:fromViewController.view];
id <CKMTransitionAnimatable> fromAnimationSource = (id <CKMTransitionAnimatable>)fromViewController;
id <CKMTransitionAnimatable> toAnimationSource = (id <CKMTransitionAnimatable>)toViewController;
CGFloat animationDelay = [fromAnimationSource transitionOutDuration];
[fromAnimationSource animateOnTransitionOut:nil];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(animationDelay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[toAnimationSource animateOnTransitionIn:^{
[transitionContext completeTransition:YES];
}];
});
}
使用自定义转换的 ViewController 将实现的协议:
typedef void (^CKMAnimationCompletionBlock)(void);
@protocol CKMTransitionAnimatable <NSObject>
- (void)animateOnTransitionIn:(CKMAnimationCompletionBlock)inAnimationCompletionBlock;
- (void)animateOnTransitionOut:(CKMAnimationCompletionBlock)inAnimationCompletionBlock;
- (NSTimeInterval)transitionInDuration;
- (NSTimeInterval)transitionOutDuration;
@end
最后是视图控制器中实际实现 CKMTransitionAnimatable 协议的代码:
- (NSTimeInterval)transitionInDuration
{
return 0.4;
}
- (NSTimeInterval)transitionOutDuration
{
return 0.4;
}
- (void)animateOnTransitionOut:(CKMAnimationCompletionBlock)inAnimationCompletionBlock
{
[UIView animateWithDuration:[self transitionOutDuration] animations:^{
self.contentView.alpha = 0;
} completion:^(BOOL finished) {
if( inAnimationCompletionBlock )
{
inAnimationCompletionBlock();
}
}];
}
- (void)animateOnTransitionIn:(CKMAnimationCompletionBlock)inAnimationCompletionBlock
{
[UIView animateWithDuration:[self transitionInDuration] animations:^{
self.contentView.alpha = 1;
} completion:^(BOOL finished) {
if( inAnimationCompletionBlock )
{
inAnimationCompletionBlock();
}
}];
}
一切看起来都很简单,但对于我的生活,我看不出我做错了什么。
【问题讨论】:
标签: ios objective-c