CGAffineTransform 影响我的 UIView 的角半径

CGAffineTransform affects the corner radius of my UIView

我正在使用以下代码将 CGAffineTransform 动画应用到 UIView:

UIView.animate(withDuration: 0.5, delay: delay, options: [.autoreverse, .repeat], animations: {
    elementView.transform = CGAffineTransform(scaleX: 1.0, y: 0.4)
}) { (finished) in

}

UIView 在动画中正确缩放,但我也将 UIView 的角半径设置为完美环绕视图的顶部和底部。

问题是,当缩放动画发生时,我的UIView的圆角半径是"squished":

如何确保圆角半径保持完美的圆角,同时保持缩放动画?

我认为你最好的选择是只更改 elementViewframe 属性:

UIView.animate(withDuration: 0.5, delay: delay, options: [.autoreverse, .repeat], animations: {
    elementView.frame = CGRect(x: elementView.frame.origin.x, y: elementView.frame.origin.y, width: elementView.frame.size.width, height: elementView.frame.size.height * 0.4)
}) { (finished) in

}

或者如果您使用的是自动布局:

heightContraint.constant = heightConstraint * 0.4
UIView.animate(withDuration: 0.5, delay: delay, options: [.autoreverse, .repeat], animations: {
    elementView.layoutIfNeeded()
}) { (finished) in

}

无论哪种方式,都应在缩短视野的同时保持拐角半径。

转换也会缩小角半径 - 我希望它会那样做。如果你想获得相同的结果,只是使用正确的角半径,你将不得不使用不同的方法。

我自己会改用高度限制:

let heightConstraint = elementView.heightAnchor.constraint(equalToConstant: 100)
heightConstraint.isActive = true

然后缩小常量:

heightConstraint.constant = heightConstraint.constant * 0.4 // (or set to constant directly)
elementView.superView.setNeedsLayout()
UIView.animate(withDuration: 0.5, delay: delay, options: [.autoreverse, .repeat], animations: {
    elementView.superView.layoutIfNeeded()
}) { (finished) in

}

解决方案:

UIView.animate(withDuration: 0.5, delay: delay, options: [.autoreverse, .repeat], animations: {
    elementView.transform = CGAffineTransform(scaleX: 1.0, y: 0.4)
    elementView.layer.cornerRadius /= 0.4 // <-- solution
}) { (finished) in

}

游乐场版本:

import UIKit
import PlaygroundSupport

let w: CGFloat = 10
let h: CGFloat = 100
let radius = w/2
let elementView = UIView(frame: CGRect(x: 10, y: 10, width: w, height: h))
elementView.backgroundColor = .red
elementView.layer.cornerRadius = radius

UIView.animate(withDuration: 0.5, delay: 0, options: [.autoreverse, .repeat], animations: {
    elementView.transform = CGAffineTransform(scaleX: 1.0, y: 0.4)
    elementView.layer.cornerRadius =/ 0.4 // <-- solution
}) { (finished) in

}

PlaygroundPage.current.liveView = elementView