之前公司业务需要,功能需求:仿照微信朋友圈,可录制10s小视频,可拍照,并且对视频和图片进行压缩,今天正好有空,对以前的功能做一个记录。
因为时间紧迫,目前刚写出一个按钮,主要功能是点击拍照,长按录制视频。
功能实现分析:首先,按钮在点击的时候会拍照,这个可以使用UITapGestureRecognizer点击手势,并且在长按的时候按钮中间图形放大,外层圆环随着录制时间而变化,长按可以使用UILongPressGestureRecognizer长按手势,圆环变化可以使用核心动画,图层,贝塞尔曲线实现。
效果如下
image
核心代码:
- 1.首先分成两个图层
/** outerView外层圆环,长按时会随着时间变化 */
_outerView = [[UIView alloc] initWithFrame:self.bounds];
_outerView.layer.cornerRadius = self.width * 0.5;
_outerView.backgroundColor = RGBColor(175, 175, 175);
_outerView.alpha = 0.9;
[self addSubview:_outerView];
/** centerView内层圆环,长按时会缩小 */
_centerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 55, 55)];
_centerView.center = _outerView.center;
_centerView.backgroundColor = [UIColor whiteColor];
_centerView.layer.cornerRadius = _centerView.width * 0.5;
[self addSubview:_centerView];
- 2.添加手势和图层
/** 长按手势 */
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
[_centerView addGestureRecognizer:longPress];
/** 点按手势 */
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];
/** 填充贝塞尔曲线宽度 */
_width = 5;
/** 添加图层 */
_progressLayer = [[CAShapeLayer alloc] init];
[_outerView.layer addSublayer:_progressLayer];
_progressLayer.fillColor = nil;
_progressLayer.lineCap = kCALineCapSquare;
_progressLayer.frame = _outerView.bounds;
_progressLayer.lineWidth = _width;
_progressLayer.strokeColor = RGBColor(90, 165, 88).CGColor;
/** 默认录制十秒 */
self.duration = 10;
- 3.长按手势动画实现
- (void)longPress:(UILongPressGestureRecognizer *)longPress
{
/** 根据手势的不同状态,做出响应 */
switch (longPress.state) {
case UIGestureRecognizerStateBegan:{
[UIView animateWithDuration:0.3 animations:^{
_centerView.transform = CGAffineTransformMakeScale(0.7, 0.7);
_outerView.transform = CGAffineTransformMakeScale(1.5, 1.5);
}];
[self start];
}
break;
case UIGestureRecognizerStateEnded:{
[UIView animateWithDuration:0.3 animations:^{
_centerView.transform = CGAffineTransformMakeScale(1.0, 1.0);
_outerView.transform = CGAffineTransformMakeScale(1.0, 1.0);
}];
[self stop];
}
break;
case UIGestureRecognizerStateChanged:
break;
case UIGestureRecognizerStateCancelled:{
[self stop];
}
break;
default:
break;
}
}
//开启定时器
- (void)start
{
_timer = [NSTimer scheduledTimerWithTimeInterval:_animatetionTime target:self selector:@selector(addProgress) userInfo:nil repeats:YES];
}
- (void)addProgress
{
dispatch_async(dispatch_get_main_queue(), ^{
//图层增加量
_progress += _animatetionIncr;
[self updateProgress];
if (_progress > 1) {
[self stop];
}
});
}
//在设置录制时间时,会计算图层每秒增加量,以及动画时间
- (void)setDuration:(NSInteger)duration
{
_duration = duration;
_animatetionTime = 1 / (CGFloat)(duration * duration);
_animatetionIncr = 1 / (CGFloat)(duration * duration * duration);
}
//更新动画
- (void)updateProgress
{
//绘制贝塞尔曲线
UIBezierPath *progessPath = [UIBezierPath bezierPathWithArcCenter:_centerView.center radius:(_outerView.width - (1.5 * _width)) / 3 startAngle:(M_PI_2 * 3) endAngle:(M_PI * 2) *_progress + (-M_PI_2) clockwise:YES];
_progressLayer.path = progessPath.CGPath;
}
- (void)setProgress
{
_progress = 0;
UIBezierPath *progessPath = [UIBezierPath bezierPathWithArcCenter:_centerView.center radius:(_outerView.width - (1.5 * _width)) / 3 startAngle:(M_PI_2 * 3) endAngle:-M_PI_2 clockwise:YES];
_progressLayer.path = progessPath.CGPath;
}
//停止录制,废弃定时器
- (void)stop
{
[_timer invalidate];
_timer = nil;
[self setProgress];
}
结尾:功能虽然不难,实现的方式也有很多种,需要注意的是对于手势中可能发生的状态做出相应的响应,以及对于定时器使用完后一定要销毁,下一篇将讲述视频录制以及压缩功能。
网友评论