【发布时间】:2021-02-12 16:52:42
【问题描述】:
我正在尝试创建一个动画,其中 CALayer 矩形从与视图的边框齐平变为具有圆角的左、右或两个角,并且矩形的宽度也发生了变化。
我遇到的问题是动画看起来失真。如果我在动画中禁用角半径更改,则不会发生失真。我怀疑这是因为当动画中的原始路径和最终路径具有不同数量的圆角时,路径具有不同数量的控制点,因此路径动画行为根据docs未定义。
我在想我应该尝试找到一种方法,使圆角矩形中的控制点数等于非圆角矩形中的数字,但我不确定我会如何做到这一点,因为我还没有找到一种方法来计算 CGPath/UIBezierPath 中控制点的数量。
这是我现在正在使用的代码,我正在为路径设置动画,但我愿意通过使用两个矩形或类似的东西将实现完全更改为“作弊”。
func setSelection(to color: UIColor, connectedLeft: Bool, connectedRight: Bool, animated: Bool) {
self.connectedLeft = connectedLeft
self.connectedRight = connectedRight
self.color = color
if animated {
let pathAnimation = CABasicAnimation(keyPath: "path")
let colorAnimation = CABasicAnimation(keyPath: "fillColor")
self.configure(animation: pathAnimation)
self.configure(animation: colorAnimation)
pathAnimation.toValue = self.rectPath(connectedLeft: connectedLeft, connectedRight: connectedRight).cgPath
colorAnimation.toValue = color.cgColor
let group = CAAnimationGroup()
group.animations = [pathAnimation, colorAnimation]
self.configure(animation: group)
group.delegate = self
self.rectLayer.add(group, forKey: Constants.selectionChangeAnimationKey)
} else {
self.rectLayer.fillColor = color.cgColor
self.rectLayer.path = self.rectPath(connectedLeft: connectedLeft, connectedRight: connectedRight).cgPath
}
}
private func rectPath(connectedLeft: Bool, connectedRight: Bool) -> UIBezierPath {
let spacing: CGFloat = 5
var origin = self.bounds.origin
var size = self.bounds.size
var corners = UIRectCorner()
if !connectedLeft {
origin.x += spacing
size.width -= spacing
corners.formUnion([.topLeft, .bottomLeft])
}
if !connectedRight {
size.width -= spacing
corners.formUnion([.topRight, .bottomRight])
}
let path = UIBezierPath(roundedRect: .init(origin: origin, size: size), byRoundingCorners: corners, cornerRadii: .init(width: 8, height: 8))
print(path.cgPath)
return path
}
【问题讨论】:
-
可以,我会试一试,但我需要能够只对一些角进行圆角处理。我可以通过使用重叠的矩形来破解它。
标签: ios swift calayer caanimation