Recently, the switC button with dynamic effect will be used in the project. The effect picture is as follows:




switch.gif

This effect needs to be combined with frame animation to achieve, and then quickly ask the UI to get a set of images…

First we need to customize a View

And make the View a rounded corner

class DynamicSwitch: UIButton { override init(frame: CGRect) { super.init(frame: frame) setupUI() } required init? (coder aDecoder: NSCoder) {fatalError("init(coder:) has not been implemented")} private func setupUI() {// round layer.cornerradius = height / 2 layer.masksToBounds = true } }Copy the code

Implement frame animation

// Frame animation for I in 1... 22 { beginImageArray.append(UIImage(named: "switch \(i).png")!) let imageView = UIImageView(image: UIImage(named: "The switch 1. PNG")) imageView. Center = the center imageView. AnimationImages = beginImageArray / / duration of the animation Each frame of 0.025 seconds, A total of 22 frame imageView. AnimationDuration = 0.025 * 22 imageView animationRepeatCount = 1 / / end of the animation of the imageView image attribute set animation last frame imageView.image = UIImage(named: "switch 22.png") imageView.startAnimating() view.addSubview(imageView) }Copy the code


image.png


At this time you can make the effect of the expression in situ rotation




switch.gif

Then we need a gradient color

Gradient can be implemented by CAGradientLayer as follows:

Let gradientLayer = CAGradientLayer() gradientLayer.frame = bounds gradientlayer. colors = [UIColor(red: 255/255.0, green: 195/255.0, blue: 113/255.0, alpha: 1). CgColor, UIColor(red: 255/255.0, green: GradientLayer = gradientLayer (x: 0, y: 1). GradientLayer = gradientLayer (x: 0, y: 1). 0) gradientLayer.endPoint = CGPoint(x: 1, y: 0) view.layer.addSublayer(gradientLayer)Copy the code

StartPoint and endPoint from (0, 0) to (1, 0) represent horizontal gradients. At this point our control will look like this:




switch.png

Animation combined with

The entire animation is actually a horizontal translation of the imageView + frame animation, and we use a bool to determine whether it is left to right or right to left:

// Call func beginAnimation() {let duration = flag? 0.0175 * 21: 0.0225 * 21 customImageView animationDuration = duration customImageView. AnimationRepeatCount = 1 isEnabled = false customImageView.animationImages = flag ? beginImageArray : endImageArray customImageView.image = flag ? UIImage(named: "switch 22.png") : UIImage(named: "switch 1.png") UIView.animate(withDuration: duration, animations: { [unowned self] in self.customImageView.minX = self.flag ? self.width - self.height : 0 }) { [unowned self] (_) in self.isEnabled = true } customImageView.startAnimating() flag = ! flag }Copy the code


switch.gif

Gradient appearance

As a final step, the gradient of the background needs to follow the movement of the expression. This can be achieved through a white view of the same size as the parent control, and the x coordinate is synchronized with the expression when clicked.




whiteview.gif


Binding frame animation




switch.gif

The basic effects are done, all that is left is to set up the borders, shadows, and some details.