Подтвердить что ты не робот

Восстановить пре-iOS7 UINavigationController pushViewController animation

Итак. Просто начал переводить мой IOS-код в IOS7 и столкнулся с некоторой проблемой.

У меня есть UINavigationController, у которого есть дочерние ViewControllers, и я использую pushViewController для отображения следующих представлений. Чтобы создать анимацию параллакса с набором изображений, при настройке UINavigationController для анимации набора UIImageViews, а у моих дочерних ViewControllers есть self.backgroundColor = [UIColor clearColor], прозрачность.

Так как iOS7, способ, в котором UINavController оживляет его дочерние vc, обновляется, частично перемещая текущий контроллер представления, а сверху нажимает новый диспетчер представлений, моя анимация параллакса выглядит дерьмо. Я вижу, что предыдущий VC движется немного, а затем исчезает. Есть ли способ восстановить предыдущую анимацию pushTecViewController UINavigationController? Я не могу найти это в коде.

WelcomeLoginViewController* welcomeLoginViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"WelcomeLogin"];
    [self.navigationController pushViewController:welcomeLoginViewController animated:YES];    

Даже попытался использовать:

    [UIView animateWithDuration:0.75
                     animations:^{
                         [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
                         [self.navigationController pushViewController:welcomeLoginViewController animated:NO];
                         [UIView setAnimationTransition:<specific_animation_form> forView:self.navigationController.view cache:NO];
                     }];

Есть ли у кого-нибудь подсказки?

4b9b3361

Ответ 1

Спасибо, ребята, за отзывы. Нашел решение, полностью воссоздающее поведение UINavigationController. Когда я почти закончил, я столкнулся с решением Ника Локвуда:

https://github.com/nicklockwood/OSNavigationController

OSNavigationController - это повторная реализация UINavigationController с открытым исходным кодом. В настоящее время он имеет только часть функциональности UINavigationController, но долгосрочная цель - реплицировать 100% функций.

OSNavigationController на самом деле не предназначен для использования как есть. Идея заключается в том, что вы можете разветкить ее, а затем легко настроить внешний вид и поведение в соответствии с любыми специальными требованиями, которые могут иметь ваше приложение. Настройка OSNavigationController намного проще, чем попытка настроить UINavigationController из-за того, что код открыт, и вам не нужно беспокоиться о частных методах, недокументированном поведении или изменениях реализации между версиями.

Переопределив мой UINavigationController своим кодом, я смог работать с фоновыми изображениями в UINavigationcontrollers

Спасибо!

Ответ 2

Мне удалось переделать новый тип перехода, создав категорию для UINavigationController. В моем случае мне нужно было вернуть его в старый стиль перехода, потому что у меня есть прозрачные viewControllers, которые скользят по статическому фону.

  • UINavigationController + Retro.h

    @interface UINavigationController (Retro)
    
    - (void)pushViewControllerRetro:(UIViewController *)viewController;
    - (void)popViewControllerRetro;
    
    @end
    
  • UINavigationController + Retro.m

    #import "UINavigationController+Retro.h"
    
    @implementation UINavigationController (Retro)
    
    - (void)pushViewControllerRetro:(UIViewController *)viewController {
        CATransition *transition = [CATransition animation];
        transition.duration = 0.25;
        transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        transition.type = kCATransitionPush;
        transition.subtype = kCATransitionFromRight;
        [self.view.layer addAnimation:transition forKey:nil];
    
        [self pushViewController:viewController animated:NO];
    }
    
    - (void)popViewControllerRetro {
        CATransition *transition = [CATransition animation];
        transition.duration = 0.25;
        transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        transition.type = kCATransitionPush;
        transition.subtype = kCATransitionFromLeft;
        [self.view.layer addAnimation:transition forKey:nil];
    
        [self popViewControllerAnimated:NO];
    }
    
    @end
    

Ответ 3

У меня та же проблема с четкими цветами фона и дрянной анимацией, поэтому я создаю настраиваемый переход для ViewController с новым API iOS7. Все, что вам нужно, это просто установить делегат для вашего контроллера навигации:

// NavigationController does not retain delegate, so you should hold it.
self.navigationController.delegate = self.navigationTransitioningDelegate;

Просто добавьте эти файлы в свой проект: MGNavigationTransitioningDelegate.

Ответ 4

У меня возникла проблема, когда, когда UIViewController A сделал pushViewController, чтобы нажимать UIViewController B, анимация push остановится примерно на 25%, остановится, а затем переместит B в остальной части пути.

Этот DID НЕ происходит на iOS 6, но как только я начал использовать iOS 7 в качестве базового SDK в XCode 5, это начало происходить.

Исправление состоит в том, что в контроллере представления B не было набора backgroundColor в его корневом представлении (корневой вид - это тот, который является значением viewController.view, которое вы обычно устанавливаете в loadView). Исправлена ​​проблема с установкой backgroundColor в этом корневом инициализаторе.

Мне удалось исправить это следующим образом:

// CASE 1: The root view for a UIViewController subclass that had a halting animation

- (id)initWithFrame:(CGRect)frame

{

     if ((self = [super initWithFrame:frame])) {

          // Do some initialization ...

          // self.backgroundColor was NOT being set

          // and animation in pushViewController was slow and stopped at 25% and paused

     }

     return self;

}

// CASE 2: HERE IS THE FIX

- (id)initWithFrame:(CGRect)frame

{

     if ((self = [super initWithFrame:frame])) {

          // Do some initialization ...

          // Set self.backgroundColor for the fix!

          // and animation in pushViewController is no longer slow and and no longer stopped at 25% and paused

          self.backgroundColor = [UIColor whiteColor]; // or some other non-clear color

     }

     return self;

}

Ответ 5

Во-первых, я не использую раскадровки. Я пробовал использовать UINavigationController + Retro. По какой-то причине UINavigationController с трудом освобождает UIViewController в верхней части стека. Здесь решение, которое работает для меня с использованием пользовательского перехода iOS 7.

  • Установите делегат для себя.

    navigationController.delegate = self;
    
  • Объявите этот UINavigationControllerDelegate.

    - (id<UIViewControllerAnimatedTransitioning>)navigationController (UINavigationController *)navigationController 
    animationControllerForOperation:(UINavigationControllerOperation)operation
    fromViewController:(UIViewController *)fromVC 
    toViewController:(UIViewController *)toVC 
    {
        TransitionAnimator *animator = [TransitionAnimator new]; 
        animator.presenting = YES;
        return animator;
    }
    

    Обратите внимание, что он будет вызван только тогда, когда для анимированного настроено значение YES. Например

    [navigationController pushViewController:currentViewController animated:YES];
    
  • Создайте класс аниматора, расширяющий NSObject. Я назвал мой TransitionAnimator, который был изменен из TeehanLax TLTransitionAnimator внутри UIViewController-Transitions-Example.

    TransitionAnimator.h

    #import <Foundation/Foundation.h>
    @interface TransitionAnimator : NSObject <UIViewControllerAnimatedTransitioning>
    @property (nonatomic, assign, getter = isPresenting) BOOL presenting;
    @end
    

    TransitionAnimator.m

    #import "TransitionAnimator.h"
    @implementation TransitionAnimator
    - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
        return 0.5f;
    }
    - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{
        UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
        UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];    
        if (self.presenting) {
            //ANIMATE VC ENTERING FROM THE RIGHT SIDE OF THE SCREEN
            [transitionContext.containerView addSubview:fromVC.view];
            [transitionContext.containerView addSubview:toVC.view];     
            toVC.view.frame = CGRectMake(0, 0, 2*APP_W0, APP_H0); //SET ORIGINAL POSITION toVC OFF TO THE RIGHT                
            [UIView animateWithDuration:[self transitionDuration:transitionContext] 
                animations:^{
                    fromVC.view.frame = CGRectMake(0, (-1)*APP_W0, APP_W0, APP_H0); //MOVE fromVC OFF TO THE LEFT
                    toVC.view.frame = CGRectMake(0, 0, APP_W0, APP_H0); //ANIMATE toVC IN TO OCCUPY THE SCREEN
                } completion:^(BOOL finished) {
                    [transitionContext completeTransition:YES];
                }];
        }else{
            //ANIMATE VC EXITING TO THE RIGHT SIDE OF THE SCREEN
        }
    }
    @end
    

    Используйте флаг представления, чтобы указать направление, в котором вы хотите оживить или когда-либо условие, которое вы предпочитаете. Здесь ссылка на ссылку Apple.

Ответ 6

Просто добавьте:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

Это:

[[self window] setBackgroundColor:[UIColor whiteColor]];

Конечный результат:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions (NSDictionary *)launchOptions {    
    [[self window] setBackgroundColor:[UIColor whiteColor]];

    // Override point for customization after application launch.
    return YES;
}

Ответ 7

Очевидно, что в iOS7 новый способ определяет ваши собственные пользовательские переходы UIViewController. Посмотрите в документах для UIViewControllerTransitioningDelegate. Кроме того, здесь ссылка на статью об этом: http://www.doubleencore.com/2013/09/ios-7-custom-transitions/

Ответ 9

Я проголосовал за @Arne, потому что считаю это самым элегантным решением этой проблемы. Я просто хотел бы добавить код, чтобы ответить на проблему @Bill из его комментария по решению @Arne. Вот цитата комментария:

Спасибо, это работает для меня. Однако, когда пользователь удаляет Back, он возвращается к обанкротившейся анимации (поскольку кнопка "Назад" не вызывает popViewControllerRetro). - Билл 3 октября в 12:36

Чтобы вызвать popViewControllerRetro при нажатии кнопки "Назад" , вы можете выполнить небольшой взлом, чтобы достичь этого. Перейдите в свой толкаемый контроллер представления, импортируйте UIViewController + Retro.h и добавьте этот код в свой метод viewWillDisappear:

- (void)viewWillDisappear:(BOOL)animated {
    if ([self.navigationController.viewControllers indexOfObject:self] == NSNotFound) {
        [self.navigationController popViewControllerRetro];
    }

    [super viewWillDisappear:animated];
}

Этот оператор if обнаружит, когда нажата кнопка "Назад" , и вызовет popViewControllerRetro из класса категории.

С уважением.