- 前言: APP当中有资讯的页面,想仿照网易新闻,模仿上拉关闭的效果。<大神忽略,小弟记录知识要点而已嗟_>
- 行动:网上搜寻看网友有没有好的实现思路,或者好的实现方式,找到了。如下参考:
http://www.qingpingshan.com/rjbc/ios/202959.html iOS网易新闻详情页上拉关闭当前页面效果 - 接下来就运用在自己的工程当中了,根据以下几步来做:
1.创建一个类,遵守<UIViewControllerAnimatedTransitioning >协议。
@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];
- 补充知识点
1.参考iOS关键帧动画的实现,关键帧动画的原理 ,iOS UIView Animation - Keyframe : http://www.devtalking.com/articles/uiview-keyframe-animation/
2.屏幕快照的原理解释,snapshotViewAfterScreenUpdates :
http://www.jianshu.com/p/11fac364403c
3.动画的放大缩小,CGAffineTransformMakeScale & CGAffineTransformScale: http://www.jianshu.com/p/0ee900339103
网友评论