一个好玩的demo
做这个demo的起因是看到了一个神经病一样的音量调节UI
这个微博里的第二张gif
直接附代码吧
感觉也没有什么值得写的地方
不过这个代码里还没实现音量按钮变色的功能
还有待研究
//
// SPTVolumeBar.m
// tmp
//
// Created by Spt on 2017/6/15.
// Copyright © 2017年 Spt. All rights reserved.
//
#import "SPTVolumeBar.h"
#import "Masonry.h"
@interface SPTVolumeBar () <CAAnimationDelegate>
@property (nonatomic, strong) UIImageView *loudspeakerImageView;
@property (nonatomic, strong) UIView *purplePoint;
@property (nonatomic, strong) UIView *line;
@end
@implementation SPTVolumeBar
- (instancetype)init {
self = [super init];
if (self) {
self.backgroundColor = [UIColor whiteColor];
self.loudspeakerImageView = ({
UIImageView *loudspeakerImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Loudspeaker"]];
UILongPressGestureRecognizer *longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressLoudspeakerImageView:)];
longPressGestureRecognizer.minimumPressDuration = 0.1f;
[loudspeakerImageView addGestureRecognizer:longPressGestureRecognizer];
loudspeakerImageView.userInteractionEnabled = YES;
loudspeakerImageView;
});
[self addSubview:self.loudspeakerImageView];
self.line = ({
UIView *line = [[UIView alloc] init];
line.backgroundColor = [UIColor grayColor];
line.layer.cornerRadius = 3.0f;
line;
});
[self addSubview:self.line];
self.purplePoint = ({
UIView *purplePoint = [[UIView alloc] init];
purplePoint.backgroundColor = [UIColor purpleColor];
purplePoint.layer.cornerRadius = 5.0f;
purplePoint;
});
[self addSubview:self.purplePoint];
[self.loudspeakerImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self);
make.centerY.equalTo(self);
make.size.mas_equalTo(self.loudspeakerImageView.image.size);
}];
[self.line mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self);
make.left.equalTo(self.loudspeakerImageView.mas_right).offset(22.0f);
make.right.equalTo(self).offset(-12.0f);
make.height.mas_equalTo(6.0f);
}];
[self.purplePoint mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.line);
make.centerX.equalTo(self.line.mas_left);
make.size.mas_equalTo(CGSizeMake(10.0f, 10.0f));
}];
}
return self;
}
- (void)setPurplePointPositionWithAngle:(double)angle {
[self.purplePoint.layer removeAnimationForKey:@"parabola"];
CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
// 首先计算一下起点
CGFloat startX = (self.loudspeakerImageView.bounds.size.width + 10.0f) * cos(angle);
CGFloat startY = CGRectGetMidX(self.loudspeakerImageView.frame) - (self.loudspeakerImageView.bounds.size.width + 10.0f) * sin(angle);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, startX, startY);
CGPathAddQuadCurveToPoint(path, NULL, startX + 40, startY - 40, CGRectGetMinX(self.line.frame) + (self.line.bounds.size.width * angle / M_PI_4) - self.purplePoint.bounds.size.width / 2.0f, CGRectGetMidY(self.line.frame));
keyframeAnimation.path = path;
CGPathRelease(path);
keyframeAnimation.duration = 0.3f;
keyframeAnimation.repeatCount = 0;
keyframeAnimation.removedOnCompletion = NO;
keyframeAnimation.fillMode = kCAFillModeBoth;
keyframeAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
self.purplePoint.hidden = NO;
[self.purplePoint.layer addAnimation:keyframeAnimation forKey:@"parabola"];
}
#pragma mark -- Actions --
- (void)longPressLoudspeakerImageView:(UILongPressGestureRecognizer *)longPressGestureRecognizer {
if (longPressGestureRecognizer.state == UIGestureRecognizerStateBegan) {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
animation.fromValue = @(0.0f);
animation.toValue = @(-M_PI_4);
animation.duration = 2.0f;
animation.delegate = self;
CGRect oldFrame = self.loudspeakerImageView.frame;
self.loudspeakerImageView.layer.anchorPoint = CGPointMake(0.0f, 0.3f);
self.loudspeakerImageView.frame = oldFrame;
[self.loudspeakerImageView.layer addAnimation:animation forKey:@"rotate"];
self.purplePoint.hidden = YES;
}
else if (longPressGestureRecognizer.state == UIGestureRecognizerStateEnded) {
if ([self.loudspeakerImageView.layer animationForKey:@"rotate"]) {
CALayer *currentLayer = (CALayer *)[self.loudspeakerImageView.layer presentationLayer];
double currentAngle = -[(NSNumber *)[currentLayer valueForKeyPath:@"transform.rotation.z"] doubleValue];
[self setPurplePointPositionWithAngle:currentAngle];
[self.loudspeakerImageView.layer removeAnimationForKey:@"rotate"];
}
}
}
#pragma mark -- CAAnimationDelegate --
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
if (flag) {
[self setPurplePointPositionWithAngle:M_PI_4];
[self.loudspeakerImageView.layer removeAnimationForKey:@"rotate"];
}
}
@end