我的应用程序的初始ViewController有2个容器视图:第一个包含一个ViewController,里面是一个UINavigationController,它控制应用程序的主要内容。初始VC的第二个容器视图是一个带UILabels的小条带,位于导航栏的正下方。
主内容VC的导航堆栈的初始VC隐藏了导航栏。所有后续的VC将显示导航条以及初始VC的第二个容器视图。当应用程序从导航堆栈的初始VC导航时,我想在第二个容器VC中进行动画。
我的问题是,我需要创建什么动画来匹配导航控制器在推/弹出VC打开/关闭导航堆栈时执行的动画?我目前正在使用:
[UIView animateWithDuration:0.27f delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.playerCardVC.frame = secondFrame;
} completion:nil];
但是当导航栏动画进入视图时,它并没有匹配。如有任何意见,不胜感激。
更新:我一直在网上搜索这个问题的答案,并试图调整在我最初的问题中发布的动画,但似乎不能完美地匹配导航栏,因为它动画进入视图。如有任何指导性意见,我将不胜感激。
从上面的描述中很难理解你的视图层次和导航设计,也许你可以发布一些截图或草图?
你可以覆盖UINavigationController的标准水平推送/弹出动画。您可以通过定义一个自定义UINavigationControllerDelegate对象和其他一些东西来实现。见下文。
像这样设置你的navController和navControllerDelegate:
UINavigationController *navigationController = [[UINavigationController alloc] init];
self.navigationControllerDelegate = [[NavigationControllerDelegate alloc] init];
navigationController.delegate = self.navigationControllerDelegate;
其中NavigationControllerDelegate类看起来像这样:
@interface NavigationControllerDelegate : NSObject <UINavigationControllerDelegate>
@end
#import "NavigationControllerDelegate.h"
#import "CrossFadePushAnimator.h"
#import "CrossFadePopAnimator.h"
@interface NavigationControllerDelegate ()
@property (nonatomic, strong) CrossFadePushAnimator* pushAnimator;
@property (nonatomic, strong) CrossFadePopAnimator* popAnimator;
@end
@implementation NavigationControllerDelegate
- (id)init
{
self = [super init];
if (self)
{
self.pushAnimator = [CrossFadePushAnimator new];
self.popAnimator = [CrossFadePopAnimator new];
}
return self;
}
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
if (operation == UINavigationControllerOperationPop)
{
return self.popAnimator;
}
else if (operation == UINavigationControllerOperationPush)
{
return self.pushAnimator;
}
return nil;
}
- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController
{
return nil;
}
pushAnimator看起来像这样:
@interface CrossFadePushAnimator ()
@property (nonatomic, strong) id<UIViewControllerContextTransitioning> transitionContext;
@end
@implementation CrossFadePushAnimator
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return AnimationDuration;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
// UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
[[transitionContext containerView] addSubview:toViewController.view];
toViewController.view.alpha = 1.0f;
// We are using CAAnimation instead of UIView animation because we need the UIToolbar blur layer to animate
CABasicAnimation *fade = [CABasicAnimation animationWithKeyPath:@"opacity"];
fade.fromValue = @0;
fade.toValue = @1;
fade.duration = [self transitionDuration:transitionContext];
fade.removedOnCompletion = YES;
fade.delegate = self;
self.transitionContext = transitionContext;
[toViewController.view.layer addAnimation:fade forKey:AnimationKey];
}
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag
{
[self.transitionContext completeTransition:![self.transitionContext transitionWasCancelled]];
self.transitionContext = nil;
}
popAnimator看起来有点像pushAnimator。
希望这对你有帮助!
从上面的描述中很难理解你的视图层次和导航设计,也许你可以发布一些截图或草图?
你可以覆盖UINavigationController的标准水平推送/弹出动画。您可以通过定义一个自定义UINavigationControllerDelegate对象和其他一些东西来实现。见下文。
像这样设置你的navController和navControllerDelegate:
UINavigationController *navigationController = [[UINavigationController alloc] init];
self.navigationControllerDelegate = [[NavigationControllerDelegate alloc] init];
navigationController.delegate = self.navigationControllerDelegate;
其中NavigationControllerDelegate类看起来像这样:
@interface NavigationControllerDelegate : NSObject <UINavigationControllerDelegate>
@end
#import "NavigationControllerDelegate.h"
#import "CrossFadePushAnimator.h"
#import "CrossFadePopAnimator.h"
@interface NavigationControllerDelegate ()
@property (nonatomic, strong) CrossFadePushAnimator* pushAnimator;
@property (nonatomic, strong) CrossFadePopAnimator* popAnimator;
@end
@implementation NavigationControllerDelegate
- (id)init
{
self = [super init];
if (self)
{
self.pushAnimator = [CrossFadePushAnimator new];
self.popAnimator = [CrossFadePopAnimator new];
}
return self;
}
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
if (operation == UINavigationControllerOperationPop)
{
return self.popAnimator;
}
else if (operation == UINavigationControllerOperationPush)
{
return self.pushAnimator;
}
return nil;
}
- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController
{
return nil;
}
pushAnimator看起来像这样:
@interface CrossFadePushAnimator ()
@property (nonatomic, strong) id<UIViewControllerContextTransitioning> transitionContext;
@end
@implementation CrossFadePushAnimator
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return AnimationDuration;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
[[transitionContext containerView] addSubview:toViewController.view];
toViewController.view.alpha = 1.0f;
// I'm using CABasicAnimation here for a specific reason, but you could also use the animation method you use above.
CABasicAnimation *fade = [CABasicAnimation animationWithKeyPath:@"opacity"];
fade.fromValue = @0;
fade.toValue = @1;
fade.duration = [self transitionDuration:transitionContext];
fade.removedOnCompletion = YES;
fade.delegate = self;
self.transitionContext = transitionContext;
[toViewController.view.layer addAnimation:fade forKey:AnimationKey];
}
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag
{
[self.transitionContext completeTransition:![self.transitionContext transitionWasCancelled]];
self.transitionContext = nil;
}
popAnimator看起来有点像pushAnimator。
希望这对你有帮助!