我有一个简单的交互式动画:与页面之间的iOS过渡相同。但是当转换完成或取消时,它有时会回到原来的位置,就像后面的效果一样。这是我的代码,你可以测试一下,看看我的意思。我该如何解决?此外,是否有更好的方法在ViewControllers之间进行交互式转换? THX
#import "NavigationControllerDelegate.h"
#import "Animator.h"
@interface NavigationControllerDelegate ()
@property (weak, nonatomic) IBOutlet UINavigationController *navigationController;
@property (strong, nonatomic) Animator* animator;
@property (strong, nonatomic) UIPercentDrivenInteractiveTransition* interactionController;
@end
@implementation NavigationControllerDelegate
- (void)awakeFromNib
{
UIPanGestureRecognizer* panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
[self.navigationController.view addGestureRecognizer:panRecognizer];
self.animator = [Animator new];
}
- (void)pan:(UIPanGestureRecognizer*)recognizer
{
UIView* view = self.navigationController.view;
if (recognizer.state == UIGestureRecognizerStateBegan) {
CGPoint location = [recognizer locationInView:view];
if (location.x < CGRectGetMidX(view.bounds) && self.navigationController.viewControllers.count > 1) { // left half
self.interactionController = [UIPercentDrivenInteractiveTransition new];
[self.navigationController popViewControllerAnimated:YES];
}
} else if (recognizer.state == UIGestureRecognizerStateChanged) {
CGPoint translation = [recognizer translationInView:view];
CGFloat d = fabs(translation.x / CGRectGetWidth(view.bounds));
[self.interactionController updateInteractiveTransition:d];
} else if (recognizer.state == UIGestureRecognizerStateEnded) {
CGPoint translation = [recognizer translationInView:view];
CGFloat d = (translation.x / CGRectGetWidth(view.bounds));
if (d > 0.5) {
[self.interactionController finishInteractiveTransition];
} else {
[self.interactionController cancelInteractiveTransition];
}
self.interactionController = nil;
}
}
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
if (operation == UINavigationControllerOperationPop) {
return self.animator;
}
return nil;
}
- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController
{
return self.interactionController;
}
@end
#import "Animator.h"
@implementation Animator
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return 1;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
CGRect screenBounds = [[UIScreen mainScreen] bounds];
UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
[[transitionContext containerView] addSubview:toViewController.view];
toViewController.view.frame = CGRectMake(-screenBounds.size.width, 0, screenBounds.size.width, screenBounds.size.height);
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
toViewController.view.frame = CGRectMake(0, 0, screenBounds.size.width, screenBounds.size.height);
fromViewController.view.frame = CGRectMake(screenBounds.size.width, 0, screenBounds.size.width, screenBounds.size.height);
} completion:^(BOOL finished) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end