簡體   English   中英

為UIView創建動畫以使其與UINavigationController push / pop一致

[英]Create an animation for UIView to coincide with UINavigationController push/pop

我的應用程序的初始ViewController具有2個容器視圖:第一個包含一個ViewController,在其中包含一個UINavigationController來控制應用程序的主要內容。 初始VC的第二個容器視圖是一個帶有UILabel的小條,它位於導航欄所在的正下方。

主要內容VC的導航堆棧的初始VC隱藏了導航欄。 所有后續的VC都將顯示導航欄以及初始VC的第二個容器視圖。 當應用程序離開導航堆棧的初始VC時,我想在第二個容器VC中創建動畫。

我的問題是,當導航控制器將VC推入/彈出導航堆棧或從導航堆棧中彈出時,我需要創建什么動畫來與Navigation Controller執行的動畫匹配? 我目前正在使用:

[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。

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM