View Controller Transition实现京东加购物车效果

这篇文章中我们主要来叙述一下上述动画效果的实现方案。主要涉及 View Controller 转场动画的知识。

我搭建了个人站点,那里有更多内容,请多多指教。点我哦!!!

Presenting a View Controller

显示一个 View Controller 主要有一下几种方式:

  • 使用 segues 自动显示 View Controller;
  • 使用 showViewController:sender: 和 showDetailViewController:sender: 方法显示 View Controller;
  • 调用 presentViewController:animated:completion: 方法依模态形式显示 View Controller

通过上述方式,我们可以将一个 View Controller 显示出来,而对于显示地形式,我们可以使用 UIKit 中预定义的形式,也可以自定义(即自定义转场动画)。

Customizing the Transition Animations

自定义转场动画中,主要包含以下几个组件:

  • Presenting View Controller(正在显示的 View Controller)
  • Animator(动画管理者)
  • Presented View Controller(要显示的 View Controller)
  • Transitioning Delegate Object(转场代理,用来提供 Animator 对象)

实现自定义转场动画,通常按照以下几个步骤来完成

  • 创建 Presented View Controller;
  • 创建 Animator;
  • 设置 Presented View Controller 的 transitioningDelegate 属性,并实现 UIViewControllerTransitioningDelegate 提供 Animator 对象;
  • 在 Presenting View Controller 中调用 presentViewController:animated:completion: 显示 Presented View Controller;

Presented View Controller

这里,我们将 Presented View Controller 本身作为其转场代理,你也可以使用单独的代理对象。

class PresentedViewController: UIViewController {
 let imageView = UIImageView(image: UIImage(named: "jd_add.jpg"))
 override func viewDidLoad() {
  super.viewDidLoad()
  // 1.设置 transitioningDelegate(转场代理)
  transitioningDelegate = self
  modalPresentationStyle = .custom
  view.addSubview(imageView)
 }
 override func viewDidLayoutSubviews() {
  super.viewDidLayoutSubviews()
  imageView.frame = CGRect(x: 0, y: 120, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height - 120)
 }
 override func touchesBegan(_ touches: Set, with event: UIEvent?) {
  self.dismiss(animated: true, completion: nil)
 }
}

Animator

Animator 作为转场动画的管理者,主要负责 Presenting 和 Dismissing 动画效果。

动画时长

/// 转场动画时长
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
 return TimeInterval(0.5)
}

执行动画

/// 执行转场动画
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
 switch type {
 case .Present:
  present(transitionContext: transitionContext)
 case .Dismiss:
  dismiss(transitionContext: transitionContext)
 }
}

Presenting 动画

/// Presenting 动画
func present(transitionContext: UIViewControllerContextTransitioning) {
 /** 1.从转场上下文中取出 Presenting/Pressented View Controller 及容器视图 */
 guard let presentingVC = transitionContext.viewController(forKey: .from) as? ViewController else {
  return
 }
 guard let presentedVC = transitionContext.viewController(forKey: .to) as? PresentedViewController else {
  return
 }
 let containerView = transitionContext.containerView
 /** 2.设置 Presenting View Controller 所显示内容的属性 */
 // 对 presentingVC 的视图内容截屏,用于 presentedVC 显示出来时的背景
 guard let presentingVCViewSnapshot = presentingVC.view.snapshotView(afterScreenUpdates: false) else {
  return
 }
 // 隐藏 presentingVC 的 view,并将其截屏添加到 containerView 中
 presentingVC.view.isHidden = true
 containerView.addSubview(presentingVCViewSnapshot)
 // 改变 presentingVCViewSnapshot 的焦点
 presentingVCViewSnapshot.layer.anchorPoint = CGPoint(x: 0.5, y: 1)
 // 更新 presentingVCViewSnapshot 的 frame
 presentingVCViewSnapshot.frame = presentingVC.view.frame
 /** 3.设置 Presented View Controller 所显示内容的属性 */
 presentedVC.view.frame = CGRect(x: 0, y: containerView.bounds.height, width: containerView.bounds.width, height: containerView.bounds.height)
 containerView.addSubview(presentedVC.view)
 /** 4.设置 Presenting 转场动画 */
 UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
  // 改变 presentingVCViewSnapshot 的 layer 的 transform,使其绕 X轴 旋转,并改变大小
  presentingVCViewSnapshot.layer.transform.m34 = -1 / 100.0
  presentingVCViewSnapshot.layer.transform = presentingVCViewSnapshot.layer.transform = CATransform3DConcat(CATransform3DMakeRotation(CGFloat(0.1), 1, 0, 0), CATransform3DMakeScale(0.85, 0.95, 1))
  // 改变 presentedVC 的 view 的 transform
  presentedVC.view.transform = CGAffineTransform(translationX: 0, y: -containerView.bounds.height)
 }) { (finished) in
  // 告知 UIKit Presenting 转场动画结束(很重要)
  transitionContext.completeTransition(true)
 }
}

Dismissing 动画

/// Dismissing 动画
func dismiss(transitionContext: UIViewControllerContextTransitioning) {
 /** 1.从转场上下文中取出容器视图、Presenting/Pressented View Controller 及其 view 的截屏 */
 let containerView = transitionContext.containerView
 guard let presentingVC = transitionContext.viewController(forKey: .from) as? PresentedViewController else {
  return
 }
 guard let presentedVC = transitionContext.viewController(forKey: .to) as? ViewController else {
  return
 }
 let subviewsCount = containerView.subviews.count
 let presentedVCViewSnapshot = containerView.subviews[subviewsCount - 2]
 /** 2.设置 Dismissing 转场动画 */
 UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
  // 将 presentedVCViewSnapshot 的 transform 恢复到初始值
  presentedVCViewSnapshot.layer.transform = CATransform3DIdentity
  // 将 presentedVC 的 view 的 transform 恢复到初始值
  presentingVC.view.transform = CGAffineTransform.identity
 }) { (finished) in
  // 使 presentedVC 的 view 显示出来,并隐藏其截屏
  presentedVC.view.isHidden = false
  presentedVCViewSnapshot.removeFromSuperview()
  // 告知 UIKit Dismissing 转场动画结束(很重要)
  transitionContext.completeTransition(true)
 }
}

Transitioning Delegate

// MARK: - 2.实现 UIViewControllerTransitioningDelegate 提供 Animator
extension PresentedViewController: UIViewControllerTransitioningDelegate {
 /// Present
 func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
  return MyAnimator(type: .Present)
 }
 /// Dismiss
 func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
  return MyAnimator(type: .Dismiss)
 }
}
Present
@IBAction func present() {
 let presentedVC = PresentedViewController()
 present(presentedVC, animated: true, completion: nil)
}

关于 View Controller Transition 就介绍到这里,你应该熟悉了其使用方法,至于博客中的动画效果,我想就没办法深究了,这是一个花费时间苦差事。如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • iOS开发中的ViewController转场切换效果实现简介

    在iOS7之前,View Controller的切换主要有4种: Push/Pop,NavigationViewController Present and dismis Modal UITabBarController addChildViewController(一般用于自定义的继承于 UIViewController 的容器子类) iOS5,调用- (void)transitionFromViewController:(UIViewController *)fromViewControll

  • iOS开发中ViewController的页面跳转和弹出模态

    ViewController 页面跳转 从一个Controller跳转到另一个Controller时,一般有以下2种: 1.利用UINavigationController,调用pushViewController,进行跳转:这种采用压栈和出栈的方式,进行Controller的管理.调用popViewControllerAnimated方法可以返回. 复制代码 代码如下: PickImageViewController *ickImageViewController = [[PickImageV

  • Android实现仿淘宝购物车增加和减少商品数量功能demo示例

    本文实例讲述了Android实现仿淘宝购物车增加和减少商品数量功能.分享给大家供大家参考,具体如下: 在前面一篇<Android实现的仿淘宝购物车demo示例>中,小编简单的介绍了如何使用listview来实现购物车,但是仅仅是简单的实现了列表的功能,随之而来一个新的问题,买商品的时候,我们可能不止想买一件商品,想买多个,或许有因为某种原因点错了,本来想买一件来着,小手不小心抖了一下,把数量错点成了三个,这个时候就涉及到一个新的功能,那就是增加和减少商品的数量,今天这篇博文,小编就来和小伙伴们

  • angularjs学习笔记之三大模块(modal,controller,view)

    今天主要跟大家详细讲解一下angularjs的三大模块: modal,controller,view. 首先跟大家说一下这三个模块之间的关系. 1.数据模型(modal)主要提供数据.它不会和视图(view)直接操作. 2.controller保存modal提供的数据,与视图进行操作. 3.view是视图,也就是页面展示. 4.总而言之,controller负责数据和视图之间的通信,就是两者的接口人.他们分工明确,实现了模块化. 一.如何使用数据模型(modal)? 讲到数据模型,我们再来看一下

  • iOS9 系统分享调用之UIActivityViewController

    UIActivityViewController类是一个标准的view controller,通个使用这个controller,你的应用程序就可以提供各种服务. 系统提供了一些通用的标准服务,例如拷贝内容至粘贴板.发布一个公告至社交网.通过email或者SMS发送内容. 应用程序同样可以自定义服务.(我的微信分享就属于自定义服务, 之后将会写一篇教程介绍) 你的应用程序负责配置.展现和解雇这个view controller. viewcontroller的配置涉及到viewcontroller需

  • Android实现的仿淘宝购物车demo示例

    本文实例讲述了Android实现的仿淘宝购物车.分享给大家供大家参考,具体如下: 夏的热情渐渐退去,秋如期而至,丰收的季节,小编继续着实习之路,走着走着,就走到了购物车,逛过淘宝或者是京东的小伙伴都知道购物车里面的宝贝可不止一件,对于爱购物的姑娘来说,购物车里面的商品恐怕是爆满,添加不进去了,以前逛淘宝的时候,小编没有想过要怎么样实现购物车,就知道在哪儿一个劲儿的逛,但是现在不一样了,小编做为一个开发者,想的就是该如何实现,捣鼓了两天的时间,用listview来实现,已经有模有样了,现在小编就来

  • Android实现购物车功能

    最近看了一些淘宝购物车的demo,于是也写了一个. 效果图如下: 主要代码如下: actvity中的代码: public class ShoppingCartActivity extends BaseActivity { private List<Test> data; private ListView mListView; private ShoppingCartAdapter adapter; private RelativeLayout rlRefresh; private TextVi

  • View Controller Transition实现京东加购物车效果

    这篇文章中我们主要来叙述一下上述动画效果的实现方案.主要涉及 View Controller 转场动画的知识. 我搭建了个人站点,那里有更多内容,请多多指教.点我哦!!! Presenting a View Controller 显示一个 View Controller 主要有一下几种方式: 使用 segues 自动显示 View Controller: 使用 showViewController:sender: 和 showDetailViewController:sender: 方法显示 V

  • Android自定义View实现loading动画加载效果

    项目开发中对Loading的处理是比较常见的,安卓系统提供的不太美观,引入第三发又太麻烦,这时候自己定义View来实现这个效果,并且进行封装抽取给项目提供统一的loading样式是最好的解决方式了. 先自定义一个View,继承自LinearLayout,在Layout中,添加布局控件 /** * Created by xiedong on 2017/3/7. */ public class Loading_view extends LinearLayout { private Context m

  • Android 自定义view实现进度条加载效果实例代码

    这个其实很简单,思路是这样的,就是拿view的宽度,除以点的点的宽度+二个点 之间的间距,就可以算出大概能画出几个点出来,然后就通过canvas画出点,再然后就是每隔多少时间把上面移动的点不断的去改变它的坐标就可以, 效果如下: 分析图: 代码如下: package com.example.dotloadview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bit

  • js实现仿购物车加减效果

    效果图:  代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style> *{ margin: 0; padding: 0; } body{ overflow-y: auto; } ul{ margin-top: 20px; border-top: 1px solid #666; } h1{ widt

  • Vue实现商品飞入购物车效果(电商项目)

    各位掘友,好久不见,最近利用工作之余开源了Vue电商项目,高仿某知名O2O买菜平台,整个项目做下来收获还是蛮多的,可以扫描下方二维码体验,本篇是项目的核心知识拆解篇,主要是拆解增加商品飞入购物车的实现过程. 点我体验 项目开源地址 感谢点星+收藏 首先我先简单的介绍下本项目所用到的技术栈: 整个项目采用 vue-cli3 脚手架搭建, Vue全家桶(vue.vuex.vue-router) . Vant UI框架 以及很多著名好用的第三方库如: axios . fastclick . bette

  • 基于JavaScript实现游戏购物车效果详解

    目录 项目展示 登陆界面 注册界面 主界面 项目展示 登陆界面 登陆界面html和js <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <tit

  • iOS程序开发之使用PlaceholderImageView实现优雅的图片加载效果

    说明 1. PlaceHolderImageView基于SDWebImage编写 2. 给定一个图片的urlString,以及一个placeholderImage就可以优雅的显示图片加载效果 效果 源码 PlaceholderImageView.h/.m // // PlaceholderImageView.h // SDWebImageViewPlaceHorder // // Created by YouXianMing on 16/9/14. // Copyright © 2016年 Yo

  • Android基于ListView实现类似QQ空间的滚动翻页与滚动加载效果

    本文实例讲述了Android基于ListView实现类似QQ空间的滚动翻页与滚动加载效果.分享给大家供大家参考,具体如下: 1. 滚动加载 listView.setOnScrollListener(new OnScrollListener() { //添加滚动条滚到最底部,加载余下的元素 @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState == OnScro

  • 详解Android实现购物车页面及购物车效果(点击动画)

    本文介绍了Android实现购物车页面及购物车效果(点击动画),分享给大家,具体如下: 效果图如下: 思路: (1)思考每个条目中的数字的更新原理. (2)购物车的动画效果. (3)购物清单怎么显示(这个我暂时没有写,如果需要的话,可以在我的简书下给我留言). 1.因为进入页面,所有的商品个数都显示为零,所以我用 ArrayList<HashMap<String, Object>> data,把商品集合都附上零: //下面把data都添加0,为了刚开始显示时,显示的是0 for (

  • Android基于ListView实现类似Market分页加载效果示例

    本文实例讲述了Android基于ListView实现类似Market分页加载效果.分享给大家供大家参考,具体如下: 最近几天研究ListView实现分页加载和滚动加载,发现可以用listView的OnScroll方法来实现,直接上代码 ListViewScroll.java package zy.lucifer.ListViewScroll; import android.app.Activity; import android.os.Bundle; import android.util.Lo

随机推荐