寫在前面
個人覺得蘋果的拍照按鈕設計,以及交互特別美觀,於是就打造一個,自定義相機界面的時候能用到
概述
自己實現的話,兩種途徑,繼承自UIControl 或者 UIButton,白色外環直接繪圖就行,內環再加個layer,因爲要做動畫
Talk is cheap , this’s my code
typedef NS_ENUM(NSUInteger, THCaptureButtonMode) {
THCaptureButtonModePhoto = 0, // default
THCaptureButtonModeVideo = 1
};
@interface THCaptureButton : UIButton
+ (instancetype)captureButton;
+ (instancetype)captureButtonWithMode:(THCaptureButtonMode)captureButtonMode;
@property (nonatomic) THCaptureButtonMode captureButtonMode;
@end
#import "THCaptureButton.h"
#define LINE_WIDTH 6.0f
#define DEFAULT_FRAME CGRectMake(0.0f, 0.0f, 66.0f, 66.0f)
@interface THPhotoCaptureButton : THCaptureButton
@end
@interface THVideoCaptureButton : THPhotoCaptureButton
@end
@interface THCaptureButton ()
@property (strong, nonatomic) CALayer *circleLayer;
@end
@implementation THCaptureButton
+ (instancetype)captureButton {
return [[self alloc] initWithCaptureButtonMode:THCaptureButtonModeVideo];
}
+ (instancetype)captureButtonWithMode:(THCaptureButtonMode)mode {
return [[self alloc] initWithCaptureButtonMode:mode];
}
- (id)initWithCaptureButtonMode:(THCaptureButtonMode)mode {
self = [super initWithFrame:DEFAULT_FRAME];
if (self) {
_captureButtonMode = mode;
[self setupView];
}
return self;
}
- (void)awakeFromNib {
[super awakeFromNib];
_captureButtonMode = THCaptureButtonModeVideo;
[self setupView];
}
- (void)setupView {
self.backgroundColor = [UIColor clearColor];
self.tintColor = [UIColor clearColor];
UIColor *circleColor = (self.captureButtonMode == THCaptureButtonModeVideo) ? [UIColor redColor] : [UIColor whiteColor];
_circleLayer = [CALayer layer];
_circleLayer.backgroundColor = circleColor.CGColor;
_circleLayer.bounds = CGRectInset(self.bounds, 8.0, 8.0);
_circleLayer.position = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
_circleLayer.cornerRadius = _circleLayer.bounds.size.width / 2.0f;
[self.layer addSublayer:_circleLayer];
}
- (void)setCaptureButtonMode:(THCaptureButtonMode)mode {
if (_captureButtonMode != mode) {
_captureButtonMode = mode;
if (mode == THCaptureButtonModeVideo) {
self.circleLayer.backgroundColor = [UIColor redColor].CGColor;
}else if (mode == THCaptureButtonModePhoto) {
self.circleLayer.backgroundColor = [UIColor whiteColor].CGColor;
}
[self.circleLayer setValue:@1 forKeyPath:@"transform.scale"];
self.circleLayer.cornerRadius = self.circleLayer.bounds.size.width/2.f;
}
}
- (void)setHighlighted:(BOOL)highlighted {
[super setHighlighted:highlighted];
if (self.selected) {
return;
}
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
scaleAnimation.duration = 0.2f;
scaleAnimation.toValue = @0.85f;
if (highlighted) {
scaleAnimation.toValue = @0.85f;
}else {
scaleAnimation.toValue = @1.0f;
}
[self.circleLayer setValue:scaleAnimation.toValue forKeyPath:@"transform.scale"];
[self.circleLayer addAnimation:scaleAnimation forKey:@"scaleAnimation"];
}
- (void)setSelected:(BOOL)selected {
[super setSelected:selected];
if (selected) {
[CATransaction disableActions];
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
CABasicAnimation *radiusAnimation = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
scaleAnimation.toValue = @0.6f;
radiusAnimation.toValue = @(self.circleLayer.bounds.size.width / 4.0f);
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.animations = @[scaleAnimation, radiusAnimation];
animationGroup.beginTime = CACurrentMediaTime() + 0.1f;
animationGroup.duration = 0.1f;
[self.circleLayer setValue:radiusAnimation.toValue forKeyPath:@"cornerRadius"];
[self.circleLayer setValue:scaleAnimation.toValue forKeyPath:@"transform.scale"];
[self.circleLayer addAnimation:animationGroup forKey:@"scaleAndRadiusAnimation"];
}else {
[CATransaction disableActions];
CABasicAnimation *radiusAnimation = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
radiusAnimation.toValue = @(self.circleLayer.bounds.size.width / 2.0f);
radiusAnimation.beginTime = CACurrentMediaTime() + 0.1f;
radiusAnimation.duration = 0.1f;
[self.circleLayer setValue:radiusAnimation.toValue forKeyPath:@"cornerRadius"];
[self.circleLayer addAnimation:radiusAnimation forKey:@"cornerRadiusAnimation"];
}
}
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextSetLineWidth(context, LINE_WIDTH);
CGRect insetRect = CGRectInset(rect, LINE_WIDTH / 2.0f, LINE_WIDTH / 2.0f);
CGContextStrokeEllipseInRect(context, insetRect);
}
@end