在这一节中,我们继续讲解UIView中的一些动画的使用,之前已经讲过了基础的用法,和spring动画的用法,在这一节中,我们将要介绍Transitions,也是一个我们经常使用到的动画
首先我们把上次的工程打开,没看上一篇文章的同学,请移步
加入、移除、隐藏 view的动画
我们知道Transitions的意思是一个过渡动画、转变动画,但是具体什么效果,我们还是不知道,接下来,我们先来看看这个动画是一个什么要样的效果?
首先我们创建一个animationContainerView,这个就是做动画的view,为什么叫做ContainerView,因为我们还要在这个view中放上其他的一些控件一起来做动画
我们将其他的控件先隐藏掉,加入动画的view看看,是什么效果
animationContainerView = UIView(frame: view.bounds)
animationContainerView?.frame = view.bounds
view.addSubview(animationContainerView!)
然后再viewDidAppear方法中,做一个transition动画
let newView = UIImageView(image: UIImage(named: "banner"))
newView.center = animationContainerView!.center
UIView.transition(with: animationContainerView!, duration: 0.83, options: [.curveEaseOut,.transitionFlipFromTop], animations: {
self.animationContainerView?.addSubview(newView)
}, completion: nil)
好我们来看看效果
我故意将动画放的很慢,这样效果就能够更明显,这里这个option有很多种效果,我就不全部展示了,这里我提两个比较不一样的
transitionCrossDissolve
这是一个渐渐显示的一个效果
将option参数换掉就行,还是直接看效果
可能模拟器的动画效果不是那么明显,大家可以自己手动实验一下
transitionCurlUp 这个是整个一个view的一个效果
上面我都是使用的addsubview来做动画,要做移除view的动画,或者隐藏的动画,直接变换方法就行,具体的操作,我就不做了
翻转效果
我们新创建一个VC-AnotherViewController
UIView.transition(from: view, to: anotherVc.view , duration: 1.0, options: [.curveEaseInOut,.transitionFlipFromLeft]) { (true) in
}
这一行代码就可以实现翻转效果
这种效果也是我们常见的
登录动画
接下来我们在我们之前做的登录页面上,加上一些Transitions的动画
说一下我想要实现的效果,当我们点击登录按钮的时候,有一个动画出现,显示当前的登录进度,就是这么一个简单的实现
一步一步来,首先,在点击按钮的时候,让label出现
//首先将lable加入到view中
//动画的view
let status = UIImageView(image: UIImage(named: "banner"))
let label = UILabel()
let message = ["连接中...","授权中...","发送认证消息...","认证失败..."]
var statusPosition = CGPoint.zero
在页面加载时将status隐藏起来
//首先将label隐藏
status.isHidden = true
status.center = loginBtn.center
view.addSubview(status)
label.frame = CGRect(x: 0, y: 0, width: status.frame.size.width, height: status.frame.size.height)
label.textAlignment = .center
label.font = UIFont(name: "HelveticaNeue", size: 18)
label.textColor = UIColor.blue
status.addSubview(label)
statusPosition = status.center
然后我们在点击的时候,调用方法 showMeesage
func showMessage(index: Int) {
label.text = message[index]
UIView.transition(with: status, duration: 0.5, options: [.curveEaseIn,.transitionFlipFromBottom], animations: {
self.status.isHidden = false
}) { (true) in
}
}
还是看一下效果
加上动效
现在连接的状态是出现了,但是这样它就不动了,我们想要这个状态不断更新,为了实现这样的操作,我们定义一个函数,这个函数是这样的,传入一个重复操作的间隔时间,再传入需要操作的方法,即一个闭包
// A delay function
func delay(seconds: Double, completion:@escaping ()->()) {
let popTime = DispatchTime.now() + Double(Int64( Double(NSEC_PER_SEC) * seconds )) / Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: popTime) {
completion()
}
}
上面这个方法的意思是,每几秒钟执行一次completion,因为我们需要更新UI,所以这个completion必须要在主线程中执行
另外我们还需要一个移除状态的方法
func removeMessage(index: Int) {
UIView.animate(withDuration: 0.5, delay: 0.0, options: [], animations: {
self.status.center.x += self.view.bounds.size.width
}) { _ in
self.status.isHidden = true
self.status.center = self.statusPosition
self .showMessage(index: index+1)
}
}
func showMessage(index: Int) {
label.text = message[index]
UIView.transition(with: status, duration: 0.5, options: [.curveEaseIn,.transitionFlipFromBottom], animations: {
self.status.isHidden = false
}) { _ in
delay(seconds: 2, completion: {
if index < self.message.count-1 {//到了最后一条消息
self.removeMessage(index: index)
}else{
}
})
}
}
看一下效果
好今天就讲到这里,马上要放假咯,收拾收拾,回家过年
欢迎大家关注我的公众号,我会定期分享一些我在项目中遇到问题的解决办法和一些iOS实用的技巧,现阶段主要是整理出一些基础的知识记录下来
文章也会同步更新到我的博客:
ppsheep.com