Как использовать UIViewControllerAnimatedTransitioning с UINavigationController?
как я могу получить пользовательские переходы (iOS7) при нажатии контроллера вида на UINavigationController
? Я попытался установить TransitioningDelegate
обоих в UINavigationController
а также на контроллере, который я нажимаю
Методы никогда не вызываются.
все примеры, которые я нахожу, используют пользовательские переходы при представлении модально.
4 ответов
@rounak имеет правильную идею, но иногда это помогает иметь готовый код без необходимости загрузки с github.
вот шаги, которые я взял:
-
сделайте свой FromViewController.м соответствует
UINavigationControllerDelegate
. Другой пример кода там говорит вам, чтобы соответствоватьUIViewControllerTransitioningDelegate
, но это только если вы представления в ToViewController.@интерфейс ViewController: UIViewController
-
верните пользовательский объект аниматора перехода в методе обратного вызова делегата в FromViewController:
- (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC { TransitionAnimator *animator = [TransitionAnimator new]; animator.presenting = (operation == UINavigationControllerOperationPush); return animator; }
-
создайте свой пользовательский класс аниматора и вставьте эти примеры методов:
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext { return 0.5f; } - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext { // Grab the from and to view controllers from the context UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; // Set our ending frame. We'll modify this later if we have to CGRect endFrame = CGRectMake(80, 280, 160, 100); if (self.presenting) { fromViewController.view.userInteractionEnabled = NO; [transitionContext.containerView addSubview:fromViewController.view]; [transitionContext.containerView addSubview:toViewController.view]; CGRect startFrame = endFrame; startFrame.origin.x += 320; toViewController.view.frame = startFrame; [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ fromViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed; toViewController.view.frame = endFrame; } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; } else { toViewController.view.userInteractionEnabled = YES; [transitionContext.containerView addSubview:toViewController.view]; [transitionContext.containerView addSubview:fromViewController.view]; endFrame.origin.x += 320; [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ toViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeAutomatic; fromViewController.view.frame = endFrame; } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; } }
по сути, аниматор-это объект, выполняющий тяжелую работу. Конечно, вы можете сделать свой UINavigationControllerDelegate отдельным объектом, но это зависит от того, как ваш архитектор приложение.
objc.сообщение io на переходах контроллера вида специально предназначено для нажатия и выскакивания контроллеров вида. http://objc.io/issue-5/view-controller-transitions.html
Я сделал эту анимацию (http://i.imgur.com/1qEyMu3.gif) исключительно на основе objc.IO post.
короче говоря, у вас должен быть класс(ы), реализующий UINavigationControllerDelegate
и UIViewControllerAnimatedTransitioning
с необходимыми методами для возврата правильного аниматора и выполнения анимации.
вы можете посмотреть мой демо-проект, который демонстрирует использование пользовательских переходов в UINavigationController
. Посмотрите наhttps://github.com/Vaberer/BlurTransition.
EDIT: просто понял, что это может не ответить на ваш вопрос. Но это альтернатива.
если вы используете раскадровку, вы можете сделать пользовательский переход, создав пользовательский сегмент.
В инспекторе атрибутов измените имя класса segue на свой пользовательский класс перехода, например MySegue
. Затем создайте MySegue
класс и реализовать -(void)perform
метод для выполнения вашего перехода.
- (void) perform{
UIViewController *source = self.sourceViewController;
UIViewController *destination = self.destinationViewController;
[UIView transitionFromView:source.view
toView:destination.view
duration:0.50f
options:UIViewAnimationOptionTransitionFlipFromTop
completion:nil];
}