自定义转换 iOS (Push/Pop)
Custom transition iOS (Push/Pop)
我在 推送 一个新的 viewController 时创建了一个自定义的放大过渡,它曾经工作得很好。现在我想在 popping viewController 时创建一个缩小效果,甚至认为最终状态是正确的,动画是错误的,因为我不知道如何确定它是推送还是弹出以及所有方法,如 isBeingPresented
return false 和 presentedViewController
始终为 nil
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
self.transitionContext = transitionContext;
UIView *containerView = [transitionContext containerView];
UIViewController *fromViewController = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = (UIViewController *) [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
[containerView addSubview:toViewController.view];
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
scaleAnimation.duration = [self transitionDuration:transitionContext];
scaleAnimation.delegate = self;
scaleAnimation.removedOnCompletion = YES;
CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
opacityAnimation.duration = [self transitionDuration:transitionContext];
opacityAnimation.delegate = self;
opacityAnimation.removedOnCompletion = YES;
if (toViewController.isBeingPresented) {
scaleAnimation.fromValue = [NSNumber numberWithDouble:0];
scaleAnimation.toValue = [NSNumber numberWithDouble:1];
opacityAnimation.fromValue = [NSNumber numberWithFloat:1];
opacityAnimation.toValue = [NSNumber numberWithFloat:0];
} else {
scaleAnimation.fromValue = [NSNumber numberWithDouble:1];
scaleAnimation.toValue = [NSNumber numberWithDouble:0];
opacityAnimation.fromValue = [NSNumber numberWithFloat:0];
opacityAnimation.toValue = [NSNumber numberWithFloat:1];
}
[toViewController.view.layer addAnimation:scaleAnimation forKey:nil];
[fromViewController.view.layer addAnimation:opacityAnimation forKey:nil];
}
您可以保存一个 UINavigationControllerOperation
变量:
-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController*)fromVC
toViewController:(UIViewController*)toVC {
self.navigationOperation = operation;
return self;
}
然后你检查它是 push 还是 pop:
if (self.navigationOperation == UINavigationControllerOperationPush) {
// push
} else if (self.navigationOperation == UINavigationControllerOperationPop) {
// pop
}
这与您上面的代码没有关联,但这将覆盖 navigationController 的默认动画..
//.h
@interface YJKit_Navigation : UINavigationController
+ (void)navigation:(UINavigationController *)navigationController withViewController:(UIViewController *)viewController push:(BOOL)isPush;
@end
//.m
@implementation YJKit_Navigation
+ (void)navigation:(UINavigationController *)navigationController withViewController:(UIViewController *)viewController push:(BOOL)isPush
{
[navigationController.view.layer addAnimation: isPush ? PushAnimation : PopAnimation forKey:nil];
isPush ? [navigationController pushViewController:viewController animated:NO] : [navigationController popViewControllerAnimated:NO];
}
@end
并像这样使用它:
[YJKit_Navigation navigation:YourUINavigationController withViewController:YourTargetUIViewController push:(BOOL)];
希望这对你也有帮助.. :)
查看我的推送变体 viewController 带有弹出动画
- (void)navigationController:(UINavigationController *)navigationController
present:(UIViewController *)viewController
animated:(BOOL)animated
completion:(void (^)(BOOL finished))completion {
self.completion = completion;
if (animated) {
CATransition *animation = [CATransition animation];
[animation setDelegate:self];
[animation setType:kCATransitionMoveIn];
[animation setSubtype:kCATransitionFromTop];
[animation setDuration:kPresentAnimationDuration];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[navigationController.view.layer addAnimation:animation forKey:kCATransition];
}
[navigationController pushViewController:viewController animated:NO];
if (!animated) {
self.completion(YES);
}
}
我在 推送 一个新的 viewController 时创建了一个自定义的放大过渡,它曾经工作得很好。现在我想在 popping viewController 时创建一个缩小效果,甚至认为最终状态是正确的,动画是错误的,因为我不知道如何确定它是推送还是弹出以及所有方法,如 isBeingPresented
return false 和 presentedViewController
始终为 nil
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
self.transitionContext = transitionContext;
UIView *containerView = [transitionContext containerView];
UIViewController *fromViewController = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = (UIViewController *) [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
[containerView addSubview:toViewController.view];
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
scaleAnimation.duration = [self transitionDuration:transitionContext];
scaleAnimation.delegate = self;
scaleAnimation.removedOnCompletion = YES;
CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
opacityAnimation.duration = [self transitionDuration:transitionContext];
opacityAnimation.delegate = self;
opacityAnimation.removedOnCompletion = YES;
if (toViewController.isBeingPresented) {
scaleAnimation.fromValue = [NSNumber numberWithDouble:0];
scaleAnimation.toValue = [NSNumber numberWithDouble:1];
opacityAnimation.fromValue = [NSNumber numberWithFloat:1];
opacityAnimation.toValue = [NSNumber numberWithFloat:0];
} else {
scaleAnimation.fromValue = [NSNumber numberWithDouble:1];
scaleAnimation.toValue = [NSNumber numberWithDouble:0];
opacityAnimation.fromValue = [NSNumber numberWithFloat:0];
opacityAnimation.toValue = [NSNumber numberWithFloat:1];
}
[toViewController.view.layer addAnimation:scaleAnimation forKey:nil];
[fromViewController.view.layer addAnimation:opacityAnimation forKey:nil];
}
您可以保存一个 UINavigationControllerOperation
变量:
-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController*)fromVC
toViewController:(UIViewController*)toVC {
self.navigationOperation = operation;
return self;
}
然后你检查它是 push 还是 pop:
if (self.navigationOperation == UINavigationControllerOperationPush) {
// push
} else if (self.navigationOperation == UINavigationControllerOperationPop) {
// pop
}
这与您上面的代码没有关联,但这将覆盖 navigationController 的默认动画..
//.h
@interface YJKit_Navigation : UINavigationController
+ (void)navigation:(UINavigationController *)navigationController withViewController:(UIViewController *)viewController push:(BOOL)isPush;
@end
//.m
@implementation YJKit_Navigation
+ (void)navigation:(UINavigationController *)navigationController withViewController:(UIViewController *)viewController push:(BOOL)isPush
{
[navigationController.view.layer addAnimation: isPush ? PushAnimation : PopAnimation forKey:nil];
isPush ? [navigationController pushViewController:viewController animated:NO] : [navigationController popViewControllerAnimated:NO];
}
@end
并像这样使用它:
[YJKit_Navigation navigation:YourUINavigationController withViewController:YourTargetUIViewController push:(BOOL)];
希望这对你也有帮助.. :)
查看我的推送变体 viewController 带有弹出动画
- (void)navigationController:(UINavigationController *)navigationController
present:(UIViewController *)viewController
animated:(BOOL)animated
completion:(void (^)(BOOL finished))completion {
self.completion = completion;
if (animated) {
CATransition *animation = [CATransition animation];
[animation setDelegate:self];
[animation setType:kCATransitionMoveIn];
[animation setSubtype:kCATransitionFromTop];
[animation setDuration:kPresentAnimationDuration];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[navigationController.view.layer addAnimation:animation forKey:kCATransition];
}
[navigationController pushViewController:viewController animated:NO];
if (!animated) {
self.completion(YES);
}
}