gpt4 book ai didi

ios - UINavigationControllerDelegate 和 UIViewControllerAnimatedTransitioning 的问题

转载 作者:行者123 更新时间:2023-11-29 12:18:14 25 4
gpt4 key购买 nike

所以我开始着手创建自定义插入/弹出转换,第一次插入转换时一切正常,但是当我尝试插入另一个 View Controller 时,我根本看不到任何动画。

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];
}];
});

}

使用自定义转换的 ViewControllers 将实现我的协议(protocol):

typedef void (^CKMAnimationCompletionBlock)(void);

@protocol CKMTransitionAnimatable <NSObject>

- (void)animateOnTransitionIn:(CKMAnimationCompletionBlock)inAnimationCompletionBlock;
- (void)animateOnTransitionOut:(CKMAnimationCompletionBlock)inAnimationCompletionBlock;
- (NSTimeInterval)transitionInDuration;
- (NSTimeInterval)transitionOutDuration;

@end

最后是 View Controller 中实际实现 CKMTransitionAnimatable 协议(protocol)的代码:

- (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();
}
}];
}

一切看起来都很简单,但就我的生活而言,我看不出我做错了什么。

最佳答案

解决了问题...看起来这是我在 animateTransition 中将 View Controller 添加到容器 View 的方式。它应该看起来像这样:

- (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];
}];
});

}

关于ios - UINavigationControllerDelegate 和 UIViewControllerAnimatedTransitioning 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31462543/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com