UIViewController - проблема с пользовательским переходом dismiss

Резюме

У меня есть контент UIViewController, который представляет настройки UIViewController с помощью пользовательского перехода. Презентация сpresentViewController:animated:completion:.

Когда я позже отклонить настройки сdismissViewControllerAnimated:completion:Контроллер представления внезапно возвращается в исходное положение до презентации контроллера настроек.

У меня есть обходной путь для этого на устройстве, но не на симуляторе. Тем не менее, я хотел бы знать, что я делаю неправильно, а не взламывать уловку, которая заставляет его уйти. Я также планирую сделать эту анимацию интерактивной, и я подозреваю, что эта проблема усилится, когда я это сделаю.

Custom Transition - Открытие капота

Желаемый эффект заключается в том, чтопредставление контроллер сдвигается вниз по экрану, ипредставленный Контроллер, видимо, лежит позади него, откуда он поднимается, чтобы заполнить экран. Верх представляемого контроллера остается на экране в течение всего срока использования представленного контроллера. Он остается в нижней части экрана, новыше представленный контроллер.

Вы можете представить, как поднимаете капот на автомобиле (передний контроллер представления), чтобы увидеть двигатель сзади (представленные настройки), но капот остается видимым внизу для некоторого контекста.

Я планирую уточнить это так, чтобы представляемый контроллер действительно отображал перспективу трехмерным способом, но я еще не дошел до этого.

Когда настройки отклоняются, первоначальный контроллер представления (капот) должен сдвинуться обратно на экран, и представленный контроллер (настройки) немного опустится назад (закрывая капот).

Код

Вот метод, который включает и выключает настройки экрана (он вызывается только кнопкой UIB). Вы заметите, что контроллер представления представляет себя как<UIViewControllerTransitioningDelegate>.

-(void) toggleSettingsViewController
{
  const BOOL settingsAreShowing = [self presentedViewController] != nil;
  if(!settingsAreShowing)
  {
    UIViewController *const settingsController = [[self storyboard] instantiateViewControllerWithIdentifier: @"STSettingsViewController"];
    [settingsController setTransitioningDelegate: self];
    [settingsController setModalPresentationStyle: UIModalPresentationCustom];
    [self presentViewController: settingsController animated: YES completion: nil];
  }
  else
  {
    [self dismissViewControllerAnimated: YES completion: nil];
  }
}

Реализовать<UIViewControllerAnimatedTransitioning> контроллер представления также просто возвращает себя как<UIViewControllerAnimatedTransitioning>

-(id<UIViewControllerAnimatedTransitioning>) animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
  return self;
}

-(id<UIViewControllerAnimatedTransitioning>) animationControllerForDismissedController:(UIViewController *)dismissed
{
  // Test Point 1.
  return self;
}

Итак, наконец, контроллер представления представления получитanimateTransition::

-(void) animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
  UIViewController *const fromController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
  UIViewController *const toController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

  const BOOL isUnwinding = [toController presentedViewController] == fromController;
  const BOOL isPresenting = !isUnwinding;

  UIViewController * presentingController = isPresenting ? fromController : toController;
  UIViewController * presentedController = isPresenting ? toController : fromController;

  if(isPresenting)
  {
    // Add the presented controller (settings) to the view hierarchy _behind_ the presenting controller.
    [[transitionContext containerView] insertSubview: [presentedController view] belowSubview: [presentingController view]];

    // Set up the initial position of the presented settings controller. Scale it down so it seems in the distance. Alpha it down so it is dark and shadowed.
    presentedController.view.transform = CGAffineTransformMakeScale(0.9, 0.9);
    presentedController.view.alpha = 0.7;

    [UIView animateWithDuration: [self transitionDuration: transitionContext] animations:^{
      // Lift up the presented controller.
      presentedController.view.transform = CGAffineTransformMakeScale(1.0, 1.0);

      // Brighten the presented controller (out of shadow).
      presentedController.view.alpha = 1;

      // Push the presenting controller down the screen – 3d effect to be added later.
      presentingController.view.layer.transform = CATransform3DMakeTranslation(0,400,0);
     } completion: ^(BOOL finished){
       [transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
     }];
  }
  else
  {
    // Test Point 2.

    // !!!This line should not be needed!!!
    // It resets the presenting controller to where it ought to be anyway.
    presentingController.view.layer.transform = CATransform3DMakeTranslation(0,400,0);

    [UIView animateWithDuration: [self transitionDuration: transitionContext] animations:^{
      // Bring the presenting controller back to its original position.
      presentingController.view.layer.transform = CATransform3DIdentity;

      // Lower the presented controller again and put it back in to shade.
      presentedController.view.transform = CGAffineTransformMakeScale(0.9, 0.9);
      presentedController.view.alpha = 0.4;
    } completion:^(BOOL finished) {
      [transitionContext completeTransition: ![transitionContext transitionWasCancelled]];
    }];
  }
}

-(NSTimeInterval) transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
  return 0.5;
}
проблема

В приведенном выше коде я указал!!! Эта строка не нужна !!!.

Что происходит, что междуКонтрольная точка 1 а такжеКонтрольная точка 2 положение экрана представляемого контроллера представления сбрасывается до пределов экрана по умолчанию. Таким образом, вместо того, чтобы находиться внизу экрана и быть готовым к плавной анимации, он внезапно подпрыгивает вверх по экрану в положение, которое также предназначено для плавной анимации!

Я пробовал различные подходы к анимации представления контроллера вниз по экрану:

Я изменил кадр своего взгляда.Я изменил трансформацию своего взгляда.Я изменил трехмерное преобразование слоя своего вида.

Во всех случаях приКонтрольная точка 1Когда запрашивается делегат перехода, контроллер представления настраивается так, как я ожидал. Однако во всех случаях приКонтрольная точка 2Контроллер представления представления потерял правильную позицию и был «очищен», чтобы иметь нормальную полноэкранную позицию, к которой я хочу его анимировать.

Во время обхода выше я явно переместил представляющий контроллер представления обратно туда, где он должен быть в начале анимации с помощью!!! Эта строка не нужна !!!, Похоже, это работает на устройстве с текущей версией iOS 7. Однако на симуляторе контроллер виден в очищенном положении, по крайней мере, для одного кадра.

Я подозреваю, что я делаю что-то еще не так, и что я собираюсь попасть в неприятности с моим обходным путем, просто маскируя другую проблему.

Есть идеи, что происходит? Спасибо!

Ответы на вопрос(2)

Ваш ответ на вопрос