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

Как я могу начать реплицировать переход контроллера пользовательского вида, который Apple использует по умолчанию в iOS 7?

Используя переходы контроллера пользовательского представления iOS 7, я хочу добиться визуального эффекта, подобного переходу контроллера представления Apple по умолчанию в iOS 7.

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

enter image description here

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

В моем подклассе для реализации <UIViewControllerAnimatedTransitioning> у меня есть следующий код для интерактивной анимации:

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

    [transitionContext.containerView addSubview:toViewController.view];
    [transitionContext.containerView addSubview:fromViewController.view];

    fromViewController.view.layer.shadowOffset = CGSizeMake(0.0, 0.0);
    fromViewController.view.layer.shadowColor = [UIColor blackColor].CGColor;
    fromViewController.view.layer.shadowRadius = 5.0;
    fromViewController.view.layer.shadowOpacity = 0.5;

    [UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
        CGRect newFrame = fromViewController.view.frame;
        newFrame.origin.x = CGRectGetWidth(fromViewController.view.bounds);

        fromViewController.view.frame = newFrame;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:!transitionContext.transitionWasCancelled];
    }];
}

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

Кто-нибудь пытался сделать что-то похожее на это и может предоставить пример кода?

Пример проекта для тестирования, если вы хотите: http://cl.ly/0B3q1b390x0D

Кредит objc.io для базового кода.

4b9b3361

Ответ 1

Установка shadowPath значительно увеличивает производительность этой тени.

Просто добавьте это в свой метод animateTransition: после того, как вы установили свойства тени. Это позволяет избежать дорогостоящего рендеринга, который обычно вызывает тень.

[fromViewController.view.layer setShadowPath:[[UIBezierPath bezierPathWithRect:fromViewController.view.bounds] CGPath]];

Я загрузил ваш образец проекта и сделал это, заикание теперь полностью исчезло.

Некоторая информация о том, что это делает здесь.

EDIT:

Ответ на манипулирование анимацией навигационной панели заключается в том, что она не выглядит так, как вы можете. Для этого вам нужно будет переопределить свой класс типа NavigationController с нуля. Адаптация перехода для панели навигации выполняется внутри контроллера контейнера (UINavigationController) и не отображается в любом месте кода.

Ответ 2

Посмотрите ECSlidingViewController Я использовал его несколько раз, если вы понимаете, как это работает, вы можете легко реализовать что-то подобное.

Если вы хотите изобрести колесо, мой ответ бесполезен, извините.

Ответ 3

Я создаю эффект, используя Dynamics. Я создаю свой собственный подкласс ViewController со следующими методами.

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil forMultipleDirections:(BOOL)isTwoDirections;
- (void)addVelocityForGesture:(UIPanGestureRecognizer *)recognizer;
- (UIDynamicItemBehavior*) itemBehaviourForView;

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

_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.parentViewController.view];
        _gravity = [[UIGravityBehavior alloc] init];
        _gravity.gravityDirection = CGVectorMake(-1.5, 0);
        [_animator addBehavior:_gravity];

        UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.view]];
        [collision addBoundaryWithIdentifier:@1 fromPoint:CGPointMake(0, 0) toPoint:CGPointMake(0, self.parentViewController.view.frame.size.height)];
        [_animator addBehavior:collision];
        [_gravity addItem:self.view];

        UIDynamicItemBehavior *itemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[self.view]];
        [itemBehavior setElasticity:0.2];
        [_animator addBehavior:itemBehavior];

Вам потребуется больше методов для добавления скорости в соответствии с направлением панорамирования, тогда вам нужно будет найти точку, в которой вы хотите убрать или скрыть childViewController в зависимости от вашего варианта использования и т.д. Я сделал это и он работает очень хорошо для меня, поскольку он использует Dynamics, он просто поддерживает iOS7 +