动画相关iOS实用技能iOS效果原理分析

iOS新闻资讯页面仿网易新闻上拉关闭效果

2017-02-21  本文已影响469人  窗外山海帆
@interface KKAnimaTool : NSObject <UIViewControllerAnimatedTransitioning>
@end

2.实现这个类的协议方法

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    return 1.2f;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    //获取转场动画开始,结束的控制器
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    //确定结束控制器的视图大小
    CGRect finalFrameForVC = [transitionContext finalFrameForViewController:toViewController];
    UIView *containerView = [transitionContext containerView];
    //设置结束控制器的视图大小
    toViewController.view.frame = finalFrameForVC;
    toViewController.view.alpha = 1.0f;
    [containerView addSubview:toViewController.view];
    [containerView sendSubviewToBack:toViewController.view];
    //开始控制器视图的快照
    UIView *snapshotView = [fromViewController.view snapshotViewAfterScreenUpdates:NO];
    snapshotView.frame = fromViewController.view.frame;
    [containerView addSubview:snapshotView];
    [fromViewController.view removeFromSuperview];
    
    //执行关键帧动画
    NSTimeInterval duration = [self transitionDuration:transitionContext];
    void (^anima)() = ^(){
        for (int i = 0; i < 5; i++) {
            //添加5帧动画,缩放Y轴的大小
            [UIView addKeyframeWithRelativeStartTime:((i/5) * duration) relativeDuration:(0.2)*duration animations:^{
                snapshotView.transform = CGAffineTransformMakeScale(1, 1 - (i+1)/5);
                snapshotView.alpha = 0.0;
            }];
        }
    };
    
    [UIView animateKeyframesWithDuration:duration delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:anima completion:^(BOOL finished) {
        
        if (finished) {
            [snapshotView removeFromSuperview];
            [transitionContext completeTransition:YES];
        }
    }];

}

3.在需要实现关闭效果的类当中,遵守协议<UINavigationControllerDelegate>,实现代理方法:

#pragma mark - 上拉关闭(仿网易云资讯)
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
    KKAnimaTool *customNavigationAnimationController = [KKAnimaTool new];
    return customNavigationAnimationController;
}

4.我的资讯界面用的WebView,在上拉的时候触发关闭的动作:

    [_detailWebView.scrollView addFooterWithTarget:self action:@selector(popLastVC)];
        _detailWebView.scrollView.footerPullToRefreshText = @"上拉关闭当前页";
        _detailWebView.scrollView.footerReleaseToRefreshText = @"释放关闭当前页";
        _detailWebView.scrollView.footerRefreshingText = @"";
- (void)popLastVC
{
    if (_detailWebView.isLoading) {
        [_detailWebView.scrollView footerEndRefreshing];
    }else{
        self.navigationController.delegate = self;
        [self.navigationController popViewControllerAnimated:YES];
    }
}

5.到此为止,可以实现上拉关闭的动画效果,但是如果按了返回键,不希望出现这种效果,那么还需要处理一下,在pop/push到新的界面的时候,代理置空:

    self.navigationController.delegate = nil;
    [self.navigationController popViewControllerAnimated:YES];
上一篇下一篇

猜你喜欢

热点阅读