0%

仿系统视频录制按钮的实现

在系统相机中,将模式切换到视频录制,点击录制按钮会有一个表明录制状态改变的形变动画,本节将实现这一个效果.实现效果图如下:

实现步骤

创建项目

继续仿系统相机模式标签切换的实现一文中创建的项目,将项目重命名为Kcamera,后面我们将实现一个完整的视频采集程序.

新建一个继承自UIButton的类CaptureButton.打开Main.storyboard,在CameraModeView实例view中,增加一个button,宽高约束为68,水平居中,与父视图底部约束为8,并修改其初始化的类名为CaptureButton.

外部白色圆环的实现

打开CaptureButton.swift文件,添加如下代码:

override func drawRect(rect: CGRect) {
    //1. 获取上下文
    let context = UIGraphicsGetCurrentContext()
    //2. 设置圆环
    CGContextSetStrokeColorWithColor(context, UIColor.whiteColor().CGColor)
    //3. 设置线宽,即圆环宽度
    CGContextSetLineWidth(context, 6)
    //4. 设置圆环大小
    let circleRect = CGRectInset(rect, 3, 3)
    //5. 绘制
    CGContextStrokeEllipseInRect(context, circleRect)
}

内部红色实心圆的实现

在CaptureButton类中增加一个属性:

var circleLayer:CALayer!

持有这个属性是为了接下来触发点击事件的时候对其进行动画.

由于我们目前是通过storyboard实例化CaptureButton,所以初始化代码可以在awakeFromNib()方法中进行:

override func awakeFromNib() {
    self.circleLayer = CALayer()
    self.circleLayer.backgroundColor = UIColor.redColor().CGColor
    self.backgroundColor = UIColor.clearColor()
    self.tintColor = UIColor.clearColor()
    self.circleLayer.frame = CGRectInset(self.bounds, 8, 8)
    self.circleLayer.cornerRadius = self.circleLayer.frame.width * 0.5
    self.layer.addSublayer(self.circleLayer)
}

编译运行程序,可以看到出现了内红外白的按钮.

按钮点击动画的实现

由于按钮在视频采集模式和拍照模式下的点击动画是有区别的,所以需要增加一个属性来进行区分:

var mode:CameraModel = .Video

按钮highlighted状态的动画

override var highlighted: Bool{
    didSet{
        let fadeAnimation = CABasicAnimation(keyPath: "opacity")
        fadeAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
        fadeAnimation.duration = 0.2
        if highlighted {
            fadeAnimation.toValue = 0
        }else{
            fadeAnimation.toValue = 1
        }
        self.circleLayer.opaque = fadeAnimation.toValue?.intValue == 0 ? false : true
        self.circleLayer.addAnimation(fadeAnimation, forKey: "fadeAnimation")
    }
}

按钮selected状态的动画

override var selected: Bool{
    didSet{
        if self.mode == .Video{
            let scaleAnimation = CABasicAnimation(keyPath: "transform.scale")
            let radiusAnimation = CABasicAnimation(keyPath: "cornerRadius")
            if selected {
                scaleAnimation.toValue = 0.6
                radiusAnimation.toValue = self.circleLayer.bounds.width/4.0
            }else{
                scaleAnimation.toValue = 1.0
                radiusAnimation.toValue = self.circleLayer.bounds.width/2.0
            }
            let animationGroup = CAAnimationGroup()
            animationGroup.animations = [scaleAnimation,radiusAnimation];
            animationGroup.beginTime = CACurrentMediaTime() + 0.2
            animationGroup.duration = 0.35
            
            self.circleLayer.setValue(scaleAnimation.toValue, forKeyPath: "transform.scale")
            self.circleLayer.setValue(radiusAnimation.toValue, forKeyPath: "cornerRadius")
            self.circleLayer.addAnimation(animationGroup, forKey: "animationGroup")

        }
        
    }
}

测试

通过@IBAction在ViewController.swift中监听CaptureButton的点击方法如下:

    @IBAction func captureBtnDidClicked(sender: CaptureButton) {
    if self.cameraModel == CameraModel.Video{
        sender.selected = !sender.selected
    }
}

在不同采集模式下点击按钮,观察动画执行效果.