CAShapeLayer 出现在视图之前
CAShapeLayer is appearing before Views
我有两个视图,它们之间有可调整大小的线(使用 CAShapeLayer 查看)。我面临的问题是,尽管图层上有动画,但它出现的速度比视图的变化快。我知道层的动画是完全不同的,但不明白我的错在哪里。如果我做错了请告诉我。
这是我层的动画代码(也用过"strokeStart",但没用):
override func layoutSubviews() {
super.layoutSubviews()
let centerX = bounds.size.width / 2
let path = CGMutablePath()
path.addLines(between: [CGPoint(x: centerX, y: 0), CGPoint(x: centerX, y: frame.height)])
dashedLayer.path = path
dashedLayer.frame = bounds
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = height
animation.toValue = bounds.size.height
height = bounds.size.height
animation.duration = 0.3
dashedLayer.add(animation, forKey: nil)
}
视图的动画代码(因为修改视图,我对 layoutIfNeeded 进行了动画处理):
UIView.animate(withDuration: 0.3, animations: {
self.view.layoutIfNeeded()
...
您当前的代码存在一些问题。目前您正在更改没有动画的路径,因此它会立即更新。另外 strokeEnd
取 0 到 1 之间的值,所以现在你的路径总是有一个完整的笔画。
您应该为路径变化而不是描边设置动画。
override func layoutSubviews() {
super.layoutSubviews()
let centerX = bounds.size.width / 2
let path = CGMutablePath()
path.addLines(between: [CGPoint(x: centerX, y: 0), CGPoint(x: centerX, y: frame.height)])
dashedLayer.path = path
dashedLayer.frame = bounds
let animation = CABasicAnimation(keyPath: "path")
animation.duration = 0.3
animation.fromValue = dashedLayer.path
animation.toValue = path
dashedLayer.add(animation, forKey: "pathAnimation")
}
我认为解决这个问题的一种简单方法是像这样为约束常量设置动画:
@IBOutlet weak var heightConstraint: NSLayoutConstraint!
UIView.animate(withDuration: 3, animations: {
self. heightConstaint.constant = 300 // This constant is the height of top big view.
self.view.layoutIfNeeded()}
CAShapeLayer 所在的视图还有一个,我称之为line View
。它的高度应限制为与 top big view
的高度相同。
在line view
中可以添加动画。这应该与您的实现类似。
override func didMoveToSuperview() {
super.didMoveToSuperview()
dashedLayer.backgroundColor = UIColor.clear.cgColor
layer.addSublayer(dashedLayer)
height = bounds.size.height
}
override func layoutSubviews() {
super.layoutSubviews()
let centerX = bounds.size.width / 2
let path = CGMutablePath()
path.addLines(between: [CGPoint(x: centerX, y: 0), CGPoint(x: centerX, y: frame.height)])
dashedLayer.path = path
dashedLayer.lineWidth = 3.0
dashedLayer.strokeColor = UIColor.blue.cgColor
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = height / bounds.size.height
animation.toValue = 1.0
animation.timingFunction = CAMediaTimingFunction.init(name: CAMediaTimingFunctionName.easeInEaseOut)
height = bounds.size.height
animation.duration = 3.0
dashedLayer.add(animation, forKey: nil)
}
这里正在扩大。你可以自己修改代码来收缩。
以下是倒车动画。
override func didMoveToSuperview() {
super.didMoveToSuperview()
dashedLayer.backgroundColor = UIColor.clear.cgColor
layer.addSublayer(dashedLayer)
height = bounds.size.height
clipsToBounds = true
}
override func layoutSubviews() {
super.layoutSubviews()
let centerX = bounds.size.width / 2
let path = CGMutablePath()
path.addLines(between: [CGPoint(x: centerX, y: 0), CGPoint(x: centerX, y: max(height , bounds.size.height) )])
dashedLayer.path = path
dashedLayer.lineWidth = 3.0
dashedLayer.strokeColor = UIColor.blue.cgColor
let animation = CABasicAnimation(keyPath: "strokeEnd")
if (height < bounds.size.height){
animation.fromValue = height / bounds.size.height
animation.toValue = 1.0}
else {
animation.fromValue = 1.0
animation.toValue = bounds.size.height / height}
animation.timingFunction = CAMediaTimingFunction.init(name: CAMediaTimingFunctionName.easeInEaseOut)
height = bounds.size.height
animation.duration = 3
dashedLayer.add(animation, forKey: nil)
}
我有两个视图,它们之间有可调整大小的线(使用 CAShapeLayer 查看)。我面临的问题是,尽管图层上有动画,但它出现的速度比视图的变化快。我知道层的动画是完全不同的,但不明白我的错在哪里。如果我做错了请告诉我。
这是我层的动画代码(也用过"strokeStart",但没用):
override func layoutSubviews() {
super.layoutSubviews()
let centerX = bounds.size.width / 2
let path = CGMutablePath()
path.addLines(between: [CGPoint(x: centerX, y: 0), CGPoint(x: centerX, y: frame.height)])
dashedLayer.path = path
dashedLayer.frame = bounds
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = height
animation.toValue = bounds.size.height
height = bounds.size.height
animation.duration = 0.3
dashedLayer.add(animation, forKey: nil)
}
视图的动画代码(因为修改视图,我对 layoutIfNeeded 进行了动画处理):
UIView.animate(withDuration: 0.3, animations: {
self.view.layoutIfNeeded()
...
您当前的代码存在一些问题。目前您正在更改没有动画的路径,因此它会立即更新。另外 strokeEnd
取 0 到 1 之间的值,所以现在你的路径总是有一个完整的笔画。
您应该为路径变化而不是描边设置动画。
override func layoutSubviews() {
super.layoutSubviews()
let centerX = bounds.size.width / 2
let path = CGMutablePath()
path.addLines(between: [CGPoint(x: centerX, y: 0), CGPoint(x: centerX, y: frame.height)])
dashedLayer.path = path
dashedLayer.frame = bounds
let animation = CABasicAnimation(keyPath: "path")
animation.duration = 0.3
animation.fromValue = dashedLayer.path
animation.toValue = path
dashedLayer.add(animation, forKey: "pathAnimation")
}
我认为解决这个问题的一种简单方法是像这样为约束常量设置动画:
@IBOutlet weak var heightConstraint: NSLayoutConstraint!
UIView.animate(withDuration: 3, animations: {
self. heightConstaint.constant = 300 // This constant is the height of top big view.
self.view.layoutIfNeeded()}
CAShapeLayer 所在的视图还有一个,我称之为line View
。它的高度应限制为与 top big view
的高度相同。
在line view
中可以添加动画。这应该与您的实现类似。
override func didMoveToSuperview() {
super.didMoveToSuperview()
dashedLayer.backgroundColor = UIColor.clear.cgColor
layer.addSublayer(dashedLayer)
height = bounds.size.height
}
override func layoutSubviews() {
super.layoutSubviews()
let centerX = bounds.size.width / 2
let path = CGMutablePath()
path.addLines(between: [CGPoint(x: centerX, y: 0), CGPoint(x: centerX, y: frame.height)])
dashedLayer.path = path
dashedLayer.lineWidth = 3.0
dashedLayer.strokeColor = UIColor.blue.cgColor
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = height / bounds.size.height
animation.toValue = 1.0
animation.timingFunction = CAMediaTimingFunction.init(name: CAMediaTimingFunctionName.easeInEaseOut)
height = bounds.size.height
animation.duration = 3.0
dashedLayer.add(animation, forKey: nil)
}
这里正在扩大。你可以自己修改代码来收缩。
以下是倒车动画。
override func didMoveToSuperview() {
super.didMoveToSuperview()
dashedLayer.backgroundColor = UIColor.clear.cgColor
layer.addSublayer(dashedLayer)
height = bounds.size.height
clipsToBounds = true
}
override func layoutSubviews() {
super.layoutSubviews()
let centerX = bounds.size.width / 2
let path = CGMutablePath()
path.addLines(between: [CGPoint(x: centerX, y: 0), CGPoint(x: centerX, y: max(height , bounds.size.height) )])
dashedLayer.path = path
dashedLayer.lineWidth = 3.0
dashedLayer.strokeColor = UIColor.blue.cgColor
let animation = CABasicAnimation(keyPath: "strokeEnd")
if (height < bounds.size.height){
animation.fromValue = height / bounds.size.height
animation.toValue = 1.0}
else {
animation.fromValue = 1.0
animation.toValue = bounds.size.height / height}
animation.timingFunction = CAMediaTimingFunction.init(name: CAMediaTimingFunctionName.easeInEaseOut)
height = bounds.size.height
animation.duration = 3
dashedLayer.add(animation, forKey: nil)
}