提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
原创|使用教程|编辑:黄竹雯|2016-08-31 14:46:07.000|阅读 598 次
概述:UIKit里最好的增加属性是UIViewPropertyAnimator,便于你定义你自己的动画曲线。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
相关链接:
基于UIView的动画block在动画属性(框架、变换,等等)之间添加过渡,轻松建立。他们创建起来是难以置信的容易,只需要几行代码:
view.alpha = 1 UIView.animate(withDuration: 2) { containerView.alpha = 0 }
你还可以添加completion blocks,当动画完成时它们将被执行,如果默认的线性运动不能运行则调整动画曲线。
然而,如果你需要创建你自己的自定义动画曲线,就需要被动画迅速启动的属性,然后迅速减速,这时会发生什么呢?另一个稍微棘手的问题是你需要取消一个运行中的动画。当然这些可以通过使用第三方库或创建一个新的动画更换目前正在进行的动画来解决,苹果增加了一个新的组件到UIKit框架,使得这个问题解决起来变得容易许多:进入UIViewPropertyAnimator。
UIViewPropertyAnimator是写得很好的且高度可扩展的API。它涵盖了许多与“旧式”UIView动画相同的功能,但能给你动画的精确编程控制。这意味着你可以暂停一个进度,在稍后的某个日期如果你愿意的话再启动它,甚至可以动态修改动画属性(比如将以前左下角的动画结束点位置改变到屏幕的右上方)。
为了探索这个新的类,我们将看几个我们在屏幕上制作的图像动画的例子。像所有的Day by Day博客一样,代码放在GitHub上(为了方便各位读者,小编已经为大家整理了,请点击这里下载)。这一次,我们要使用一个Playground。
我们所有的Playground页面都有一个忍者在屏幕上移动。为了使页面尽可能的贴切,我们将我们共同的代码隐藏在Sources文件夹里。这不仅是帮助你简化你的页面的代码,也使他们的运行速度同源被编译了一样快。
源包含一个简单的UIView子类,叫做NinjaContainerView。这个通过用显示我们的忍者的UIImageView子视图简单设置了视图。我已将图像添加到Playground的Resources组里。
import UIKit public class NinjaContainerView: UIView { public let ninja: UIImageView = { let image = UIImage(named: "ninja") let view = UIImageView(image: image) view.frame = CGRect(x: 0, y: 0, width: 45, height: 39) return view }() public override init(frame: CGRect) { // Animating view super.init(frame: frame) // Position ninja in the bottom left of the view ninja.center = { let x = (frame.minX + ninja.frame.width / 2) let y = (frame.maxY - ninja.frame.height / 2) return CGPoint(x: x, y: y) }() // Add image to the container addSubview(ninja) backgroundColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1) } required public init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } /// Moves the ninja view to the bottom right of its container, positioned just inside. public func moveNinjaToBottomRight() { ninja.center = { let x = (frame.maxX - ninja.frame.width / 2) let y = (frame.maxY - ninja.frame.height / 2) return CGPoint(x: x, y: y) }() } }
现在,在每个Playground页面,我们可以复制和粘贴以下代码:
import UIKit import PlaygroundSupport // Container for our animating view let containerView = NinjaContainerView(frame: CGRect(x: 0, y: 0, width: 400, height: 400)) let ninja = containerView.ninja // Show the container view in the Assistant Editor PlaygroundPage.current.liveView = containerView
这将使用Playground有用的“Live View”功能,无需启动模拟器就可以给我们一个我们的动画的可视化演示。他们仍然有自己的方式,但Playgrounds是尝试新东西的明智之举。
要显示Live View窗格,导航到View > Assistant Editor > Show Assistant Editor,或者,选择在工具栏中右上方看起来像两个相交圆的图标。如果你在Assistant Editor中没有看到Live View,要确保已选择了Timeline,而不是Manual,比起我认识到这一点,我已经失去了更多的时间!
我们可以用同旧式的基于block的API完全相同的方式使用UIViewPropertyAnimator :
UIViewPropertyAnimator(duration: 1, curve: .easeInOut) { containerView.moveNinjaToBottomRight() }.startAnimation()
这将启动一个持续1秒的动画,有一个简化后的时间曲线。执行的动画在关闭中。
请注意,我们必须通过调用startAnimation()明确启动动画。另一种方法来创建无需自身启动的动画是使用runningPropertyAnimator(withDuration:delay:options:animations:completion:)——一个公平的mouthful,所以你可能更喜欢使用手动启动版。
在动画已经创建之后,添加额外的动画是很容易的。
// Now we've set up our view, let's animate it with a simple animation let animator = UIViewPropertyAnimator(duration: 1, curve: .easeInOut) // Add our first animation block animator.addAnimations { containerView.moveNinjaToBottomRight() } // Now here goes our second animator.addAnimations { ninja.alpha = 0 }
这些动画blocks会跑在一起。
Completion blocks可以以类似的方式添加:
animator.addCompletion { _ in print("Animation completed") } animator.addCompletion { position in switch position { case .end: print("Completion handler called at end of animation") case .current: print("Completion handler called mid-way through animation") case .start: print("Completion handler called at start of animation") } }
在动画被允许运行它的整个持续时间的情况下,我们将看到以下版块:
Animation completed Completion handler called at end of animation
我们可以使用animator来滑动我们的动画:
let animator = UIViewPropertyAnimator(duration: 5, curve: .easeIn) // Add our first animation block animator.addAnimations { containerView.moveNinjaToBottomRight() } let scrubber = UISlider(frame: CGRect(x: 0, y: 0, width: containerView.frame.width, height: 50)) containerView.addSubview(scrubber) let eventListener = EventListener() eventListener.eventFired = { animator.fractionComplete = CGFloat(scrubber.value) } scrubber.addTarget(eventListener, action: #selector(EventListener.handleEvent), for: .valueChanged)
分数与时间无关,所以我们看不到我们的忍者在一个像我们定义的优雅的easeIn曲线上移动。
属性动画的真正力量来自于能够中断正在进行的动画的能力。我们可以通过简单的切换isReversed属性来反向移动动画。
为了说明这一点,我们使用关键帧动画,这样我们就可以定义一个多级动画:
animator.addAnimations { UIView.animateKeyframes(withDuration: animationDuration, delay: 0, options: [.calculationModeCubic], animations: { UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.5) { ninja.center = containerView.center } UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) { containerView.moveNinjaToBottomRight() } }) } let button = UIButton(frame: CGRect(origin: .zero, size: CGSize(width: 100, height: 30))) button.setTitle("Reverse", for: .normal) button.setTitleColor(.black(), for: .normal) button.setTitleColor(.gray(), for: .highlighted) let listener = EventListener() listener.eventFired = { animator.isReversed = true } button.addTarget(listener, action: #selector(EventListener.handleEvent), for: .touchUpInside) containerView.addSubview(button) animator.startAnimation()
当按下按钮,属性动画将反转动画,如果其状态是激活的(即动画目前在运行中,忍者尚未到达其最终目的地)。
属性动画是很简单的,其余是漂亮的扩展。如果你需要另一种苹果所提供的动画曲线,你可以通过你自己符合UITimingCurveProvider协议的情况。在大多数情况下,你可能会使用UICubicTimingParameters或UISpringTimingParameters。
我们说我们的忍者加速真的很快,然后在屏幕上他们的旅途中出现一个渐进的停止。我们将使用Bezier曲线,如下图(使用这个方便的在线工具绘制)。
let bezierParams = UICubicTimingParameters(controlPoint1: CGPoint(x: 0.05, y: 0.95), controlPoint2: CGPoint(x: 0.15, y: 0.95)) let animator = UIViewPropertyAnimator(duration: 4, timingParameters:bezierParams) animator.addAnimations { containerView.moveNinjaToBottomRight() } animator.startAnimation()
新的属性动画通过带来在一致的API下的现有能力,看起来会让动画项目比以往任何时候都容易,增加了中断动画和你自己的自定义时序曲线的能力。
苹果提供了一些优秀的UIViewPropertyAnimator文件。或者,你可以观看WWDC演讲,将在新的API进行深入研究和探讨可以用来如何创建UIViewControllers之间的自定义转换。其他有趣的演示也包括了简单的游戏。
本文翻译自:
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn
本文探讨 SQL Server 中 NULL 和空值之间的区别,并讨论如何有效地处理它们。
Unity 是一款功能极其丰富的游戏引擎,允许开发人员将各种媒体集成到他们的项目中。但是,它缺少最令人兴奋的功能之一 - 将 Web 内容(例如 HTML、CSS 和 JavaScript)直接渲染到 3D 场景中的纹理上的能力。在本文中,我们将介绍如何使用 DotNetBrowser 在 Unity3D 中将 Web 内容渲染为纹理。
DevExpress v24.2帮助文档正式发布上线了,请按版本按需下载~
本教程将向您展示如何用MyEclipse构建一个Web项目,欢迎下载最新版IDE体验!
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@pclwef.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢