Fade in/out 一系列点的动画
Fade in/out animation for a series of dots
我有一个上传 UIButton
并且我正在尝试实现一个动画,其中我有一组单独的点在按钮下方水平排列并且最左边的点淡出 in/out ,然后让它旁边的点淡出 in/out,依此类推一直到最右边的点,然后从左边重新开始循环。我可以让这个对一个点起作用,但是对多个点来说最有效的方法是什么?
func dotAnimation(){
let xCoord = self.recButt.frame.origin.x + 25
let yCoord = self.recButt.frame.origin.y + 5
let radius = 3
let dotPath = UIBezierPath(ovalIn: CGRect(x: Int(xCoord), y: Int(yCoord), width: radius, height: radius))
let layer = CAShapeLayer()
layer.path = dotPath.cgPath
layer.strokeColor = UIColor(red: 95.00/255, green: 106.00/255, blue: 255/255, alpha: 1.00).cgColor
self.view.layer.addSublayer(layer)
let animation : CABasicAnimation = CABasicAnimation(keyPath: "opacity");
animation.autoreverses = true
animation.fromValue = 0
animation.toValue = 1
animation.duration = 2.0
layer.add(animation, forKey: nil)
}
您正在描述 CAReplicatorLayer。这是一个做你想要的事情的人,使用条而不是点:
这是它的代码。注意只有一个红条层;复制成五个,偏移淡化动画,由包含复制器层处理:
let lay = CAReplicatorLayer()
lay.frame = CGRect(0,0,100,20)
let bar = CALayer()
bar.frame = CGRect(0,0,10,20)
bar.backgroundColor = UIColor.red.cgColor
lay.addSublayer(bar)
lay.instanceCount = 5
lay.instanceTransform = CATransform3DMakeTranslation(20, 0, 0)
let anim = CABasicAnimation(keyPath: #keyPath(CALayer.opacity))
anim.fromValue = 1.0
anim.toValue = 0.2
anim.duration = 1
anim.repeatCount = .infinity
bar.add(anim, forKey: nil)
lay.instanceDelay = anim.duration / Double(lay.instanceCount)
// and now just add `lay` to the interface
这里是动画三点任意的另一个版本UILabel
private var displayLink: CADisplayLink?
private var loadingLabeltext: String = ""
private var loadingLabel: UILabel? = {
let label = UILabel()
label.textColor = UIColor.appRed
label.textAlignment = .center
label.font = UIFont.init(name: "CirceRounded-Bold", size: 15)
label.minimumScaleFactor = 0.6
return label
}()
override func viewDidLoad(_ animated: Bool) {
super.viewDidLoad(animated)
view.addSubview(loadingLabel!)
loadingLabel!.text = "Loading ..."
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
animateLabelDots(label: loadingLabel!)
}
private func animateLabelDots(label: UILabel) {
guard var text = label.text else { return }
text = String(text.dropLast(3))
loadingLabeltext = text
displayLink = CADisplayLink(target: self, selector: #selector(showHideDots))
displayLink?.add(to: .main, forMode: .common)
displayLink?.preferredFramesPerSecond = 4
}
@objc private func showHideDots() {
if !loadingLabeltext.contains("...") {
loadingLabeltext = loadingLabeltext.appending(".")
} else {
loadingLabeltext = "Loading "
}
loadingLabel!.text = loadingLabeltext
}
当您想停止它时,只需像这样使显示 link 无效并初始化即可:
private func hideLoadingSpinner() {
displayLink?.invalidate()
displayLink = nil
UIView.animate(withDuration: 0.5, animations: {
loadingLabel?.text = "Finished!"
loadingLabel?.alpha = 0
})
}
我有一个上传 UIButton
并且我正在尝试实现一个动画,其中我有一组单独的点在按钮下方水平排列并且最左边的点淡出 in/out ,然后让它旁边的点淡出 in/out,依此类推一直到最右边的点,然后从左边重新开始循环。我可以让这个对一个点起作用,但是对多个点来说最有效的方法是什么?
func dotAnimation(){
let xCoord = self.recButt.frame.origin.x + 25
let yCoord = self.recButt.frame.origin.y + 5
let radius = 3
let dotPath = UIBezierPath(ovalIn: CGRect(x: Int(xCoord), y: Int(yCoord), width: radius, height: radius))
let layer = CAShapeLayer()
layer.path = dotPath.cgPath
layer.strokeColor = UIColor(red: 95.00/255, green: 106.00/255, blue: 255/255, alpha: 1.00).cgColor
self.view.layer.addSublayer(layer)
let animation : CABasicAnimation = CABasicAnimation(keyPath: "opacity");
animation.autoreverses = true
animation.fromValue = 0
animation.toValue = 1
animation.duration = 2.0
layer.add(animation, forKey: nil)
}
您正在描述 CAReplicatorLayer。这是一个做你想要的事情的人,使用条而不是点:
这是它的代码。注意只有一个红条层;复制成五个,偏移淡化动画,由包含复制器层处理:
let lay = CAReplicatorLayer()
lay.frame = CGRect(0,0,100,20)
let bar = CALayer()
bar.frame = CGRect(0,0,10,20)
bar.backgroundColor = UIColor.red.cgColor
lay.addSublayer(bar)
lay.instanceCount = 5
lay.instanceTransform = CATransform3DMakeTranslation(20, 0, 0)
let anim = CABasicAnimation(keyPath: #keyPath(CALayer.opacity))
anim.fromValue = 1.0
anim.toValue = 0.2
anim.duration = 1
anim.repeatCount = .infinity
bar.add(anim, forKey: nil)
lay.instanceDelay = anim.duration / Double(lay.instanceCount)
// and now just add `lay` to the interface
这里是动画三点任意的另一个版本UILabel
private var displayLink: CADisplayLink?
private var loadingLabeltext: String = ""
private var loadingLabel: UILabel? = {
let label = UILabel()
label.textColor = UIColor.appRed
label.textAlignment = .center
label.font = UIFont.init(name: "CirceRounded-Bold", size: 15)
label.minimumScaleFactor = 0.6
return label
}()
override func viewDidLoad(_ animated: Bool) {
super.viewDidLoad(animated)
view.addSubview(loadingLabel!)
loadingLabel!.text = "Loading ..."
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
animateLabelDots(label: loadingLabel!)
}
private func animateLabelDots(label: UILabel) {
guard var text = label.text else { return }
text = String(text.dropLast(3))
loadingLabeltext = text
displayLink = CADisplayLink(target: self, selector: #selector(showHideDots))
displayLink?.add(to: .main, forMode: .common)
displayLink?.preferredFramesPerSecond = 4
}
@objc private func showHideDots() {
if !loadingLabeltext.contains("...") {
loadingLabeltext = loadingLabeltext.appending(".")
} else {
loadingLabeltext = "Loading "
}
loadingLabel!.text = loadingLabeltext
}
当您想停止它时,只需像这样使显示 link 无效并初始化即可:
private func hideLoadingSpinner() {
displayLink?.invalidate()
displayLink = nil
UIView.animate(withDuration: 0.5, animations: {
loadingLabel?.text = "Finished!"
loadingLabel?.alpha = 0
})
}