如何使 UIView 以精确的角半径在 UIView.animate() 中增长?

How to make a UIView grow in UIView.animate() with an accurate corner radius?

我有这个项目SwiftySwitch

我的目标是使圆扩大并有损于保持圆的形式,而不是在动画的每个特定时刻都有一个大于当前圆高度的角半径。

处理圆圈增长的代码在这里:

func turnOn() {
    let tempView = UIView(frame: CGRect(x: ballDiameter / 2, y: ballDiameter / 2, width: 0, height: 0))
    tempView.backgroundColor = onColor
    tempView.layer.cornerRadius = ballDiameter / 2
    self.addSubview(tempView)

    UIView.animate(withDuration: dotTravelTime, animations: { [weak self] in

        //RIGHT HERE is the code for the circle to hold it's circular form
        if self != nil {
            tempView.frame = CGRect(x: 0, y: 0, width: self!.ballDiameter, height: self!.ballDiameter)
            tempView.layer.cornerRadius = self!.ballDiameter / 2
        }
        self?.layoutIfNeeded()

    }) { [weak self] _ in
        self?.backgroundColor = self!.onColor
        tempView.removeFromSuperview()
    }
}

func turnOff() {
    let tempView = UIView(frame: CGRect(x: 0, y: 0, width: ballDiameter, height: ballDiameter))
    tempView.backgroundColor = onColor
    self.addSubview(tempView)
    self.backgroundColor = offColor

    UIView.animate(withDuration: dotTravelTime, animations: { [weak self] in

        //RIGHT HERE is the code for the circle to hold it's circular form
        if self != nil {
            tempView.frame = CGRect(x: self!.ballDiameter / 2, y: self!.ballDiameter / 2, width: 0, height: 0)
            tempView.layer.cornerRadius = self!.ballDiameter / 2
        }
        self?.layoutIfNeeded()

    }) { _ in
        tempView.removeFromSuperview()
    }
}

我说的 RIGHT HERE 就是我处理圆形动画的地方。我使用临时 UIView 来处理动画,然后在更改其背后的实际视图的颜色后删除视图。 tempView 就是你看到的随着滑动动画变化的圆形 Switch。如果您需要有关我的设计的任何信息,请告诉我。我尝试了很多东西,所有的解决方案都是圆是正方形或者圆角半径比我想要的稍大。 (我认为它比原来的尺寸缩小了一些角半径,但它很小。

My goal is to make the circle expand and detract maintaining the form of a circle

那就不要按"stupid"的方式绕圈了(cornerRadius)。蒙版到圆形路径并为蒙版的增长/收缩设置动画(and/or 路径)。

在这个例子中,我将黄色视图连同它的遮罩一起生长。动画故意放慢(持续 2 秒),以向您展示这可以顺利进行。黄色视图包含左上角的标签和右下角的标签,因此您可以看到(1)它是一个视图并且(2)它连贯地增长。

圆角半径是 属性 CALayer 而不是 UIView。不幸的是,UIView 动画方法只会捕获 UIView 相关属性的键值更改。您仍然可以单独为层属性设置动画,但您需要使用 CABasicAnimation 来执行此操作。或者,您可以实现 drawRect 并仅使用 UIBezierPath 绘制一个圆,而不是使用圆角半径。