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

三世轮回 提交于 2019-12-02 20:31:48

问题


I have this project SwiftySwitch.

My goal is to make the circle expand and detract maintaining the form of a circle instead of having a corner radius that is larger than the current circle height in each specific moment of the animation.

This code handling the circle growing is here:

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()
    }
}

Where I say RIGHT HERE is the place where I handle the circle animation. I use a temp UIView to handle the animation and then remove the view after changing the color of the actual view behind it. The tempView is the circle Switch that you see change with the sliding animation. If you need any information about my design let me know. I tried a lot of things, and the all resolved with the circle being a square or having slightly larger corner radius than I desired. (I think it is shrinking the corner radius some from the original size, but it is minor.


回答1:


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

Then don't make a circle in the "stupid" way (cornerRadius). Mask to a circular path and animate the growth / shrinkage of the mask (and/or the path).

In this example, I grow the yellow view along with its mask. The animation is deliberately slow (2-second duration) to show you that this works smoothly. The yellow view contains a label at the top left and a label at the bottom right, so that you can see that (1) it is a view and (2) it grows coherently.




回答2:


The corner radius is a property of CALayer and not UIView. Unfortunately the UIView Animation methods are only going to capture key-value changes for UIView related properties. You can still separately animate the layer properties but you need to do this with a CABasicAnimation instead. Alternatively you can implement drawRect and just draw a circle with UIBezierPath instead of using the corner radius.



来源:https://stackoverflow.com/questions/41523638/how-to-make-a-uiview-grow-in-uiview-animate-with-an-accurate-corner-radius

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!