【问题标题】:Issues with UINavigationControllerDelegate and UIViewControllerAnimatedTransitioningUINavigationControllerDelegate 和 UIViewControllerAnimatedTransitioning 的问题
【发布时间】: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


    【解决方案1】:

    解决了这个问题...看起来这是我将视图控制器添加到 animateTransition 中的容器视图的方式。它应该是这样的:

    - (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:fromViewController.view];
    
    
        id <CKMTransitionAnimatable> fromAnimationSource = (id <CKMTransitionAnimatable>)fromViewController;
        id <CKMTransitionAnimatable> toAnimationSource = (id <CKMTransitionAnimatable>)toViewController;
    
        [fromAnimationSource animateOnTransitionOut:nil];
        CGFloat animationDelay = [fromAnimationSource transitionOutDuration];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(animationDelay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [containerView addSubview:toViewController.view];
            [toAnimationSource animateOnTransitionIn:^{
                [transitionContext completeTransition:YES];
            }];
        });
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-12
      • 1970-01-01
      • 1970-01-01
      • 2019-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-20
      相关资源
      最近更新 更多