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

时间: 2024-09-25 14:04:30

View Controller Transition实现京东加购物车效果的相关文章

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

Swift:超炫的View Controller切换动画

匿名社交应用Secret的开发者开发了一款叫做Ping的应用,用户可以他们感兴趣的话题的推送. Ping有一个很炫的东西,就是主界面和之间切换的动画做的非常的好.每次看到一个非常炫的动画,都不由得会想:"这个东西我要不要自己实现以下".哈哈~~~ 这个教程里,你会学到如何用Swift实现这样的很酷的动画.你会学到如何使用shape layer,遮罩和使用UIViewControllerAnimnatedTransitioning协议和UIPercentDrivenInteractive

android 关于京东app购物车界面的问题(如图)

问题描述 android 关于京东app购物车界面的问题(如图) 解决方案 Android 仿京东购物车 解决方案二: 那个自定义控件自己写一个不难吧..下面那个应该是布局用的RelationLayout或者Framlayout之类的吧..让它处于整个布局下面就行了啊 解决方案三: 可以写成悬浮的view 解决方案四: 自己写一个不就完了.....点右边++点左边-- 解决方案五: <?xml version="1.0" encoding="utf-8"?&g

Modal View Controller Example[转]

In your iPhone app, you'll probably be spending most of the time pushing new view controllers to the stack in order to show screen flow. Sometimes, though, you just want to popup a screen for quick display or input. Here's a quick demo/tutorial on th

Applications are expected to have a root view controller at the end of application launch

问题:Applications are expected to have a root view controller at the end of application launch 环境:XCode4.2 场景:这种问题多发生在XCode4.2 移植低版本项目时出现. 原因:在iOS5下,应用加载时,需要一个root view controller,在iOS5以下的版本会有MainWindow作为启动文件,iOS5以上没有了. 解决方案:手动创建一个root view controller,

Android绚丽加载效果视图(loading)控件

http://www.see-source.com/androidwidget/list.html?type=7 AndroidProgressLayout 可根据加载情况显示提示信息的控件 GoogleProgressBar 用Android实现了google中几种风格的进度条 Titanic 实现动态波浪形动画逐渐填充TextView,可以用在加载 BounceProgressBar 跳跃波浪动画效果的ProgressBar,类似与桌面 CircularProgress 一个模仿androi

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

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

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

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