我将如何开始复制Apple在iOS 7中用作默认视图的自定义视图控制器转换?

问题描述 投票:19回答:3

[使用iOS 7的自定义视图控制器过渡,我想获得类似于iOS 7中Apple的默认视图控制器过渡的视觉效果。

((您可以在其中滑动视图控制器,方法是从左向右滑动视图控制器,而顶部视图控制器会在另一个控制器的顶部滑动并带有阴影,并且导航栏会移动。)] >

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9ya1B1Qy5wbmcifQ==” alt =“在此处输入图像说明”>

不过,实现这一点非常困难。自定义视图控制器的大多数教程都具有与默认效果大不相同的效果,以显示该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方法也是如此,而且我无法弄清楚如何操作导航栏

有人尝试做与此类似的事情并且能够提供示例代码吗?

如果需要,请抽样测试项目:https://dzwonsemrish7.cloudfront.net/items/43260h1u1T1u010i0V3C/DefaultVCTransition.zip

贷给objc.io作为基本代码。

[使用iOS 7的自定义视图控制器过渡,我想获得类似于iOS 7中Apple的默认视图控制器过渡的视觉效果。

设置shadowPath大大提高了此阴影的性能。
只需在设置阴影属性后将其添加到animateTransition:方法中。这避免了阴影通常导致的昂贵的屏幕外渲染。

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

我下载了您的示例项目,然后完成了结结巴巴。

有关此功能的一些信息here

编辑:

有关操纵导航栏动画的答案是,看来您似乎做不到。为此,您将需要从头开始重新实现自己的NavigationController类型的类。导航栏的过渡动画是由容器视图控制器(UINavigationController)在内部完成的,并且未在代码中的任何位置出现。

[看过ECSlidingViewController,我已经使用了几次,如果您了解它是如何工作的,则可以轻松实现类似的东西。
如果您想重新发明轮子,对不起,我的回答是没有用。

我使用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 +

ios objective-c ios7 uiview uiviewcontroller
3个回答
2
投票

0
投票
如果您想重新发明轮子,对不起,我的回答是没有用。

0
投票
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil forMultipleDirections:(BOOL)isTwoDirections; - (void)addVelocityForGesture:(UIPanGestureRecognizer *)recognizer; - (UIDynamicItemBehavior*) itemBehaviourForView;
© www.soinside.com 2019 - 2024. All rights reserved.