123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- //
- // FUSwitch.m
- // Interest inducing
- //
- // Created by 刘祺旭 on 15/4/13.
- // Copyright (c) 2015年 . All rights reserved.
- //
- #import "FUSwitch.h"
- #define FUSwitchMaxHeight 80.0f
- #define FUSwitchMinHeight 20.0f
- #define FUSwitchMinWidth 40.0f
- @interface FUSwitch ()<UIGestureRecognizerDelegate>
- @property (nonatomic, strong) UIView *containerView;
- @property (nonatomic, strong) UIView *onContentView;
- @property (nonatomic, strong) UIView *offContentView;
- @property (nonatomic, strong) UIColor *onColor;
- @property (nonatomic, assign) NSInteger ballSize;
- @property (nonatomic, strong) UIFont * font;
- @property (nonatomic, strong) UIColor *offColor;
- @property (nonatomic, strong) UIView *knobView;
- @property (nonatomic, strong) UILabel *onLabel;
- - (void)commonInit;
- - (CGRect)roundRect:(CGRect)frameOrBounds;
- - (void)handleTapTapGestureRecognizerEvent:(UITapGestureRecognizer *)recognizer;
- - (void)handlePanGestureRecognizerEvent:(UIPanGestureRecognizer *)recognizer;
- @end
- @implementation FUSwitch
- - (id)initWithFrame:(CGRect)frame onColor:(UIColor *)onColor offColor:(UIColor *)offColor font:(UIFont *)font ballSize:(NSInteger )ballSize
- {
- self = [super initWithFrame:[self roundRect:frame]];
- if (self) {
- self.ballSize = ballSize;
- self.font = font;
- self.onColor = onColor;
- self.offColor = offColor;
- [self commonInit];
- }
- return self;
- }
- - (id)initWithCoder:(NSCoder *)aDecoder
- {
- self = [super initWithCoder:aDecoder];
-
- if (self) {
- [self commonInit];
- }
-
- return self;
- }
- - (void)setBounds:(CGRect)bounds
- {
- [super setBounds:[self roundRect:bounds]];
-
- [self setNeedsLayout];
- }
- - (void)setFrame:(CGRect)frame
- {
- [super setFrame:[self roundRect:frame]];
-
- [self setNeedsLayout];
- }
- - (void)setOnText:(NSString *)onText
- {
- if (_onText != onText) {
- _onText = onText;
-
- _onLabel.text = onText;
- }
- }
- - (void)setOffText:(NSString *)offText
- {
- if (_offText != offText) {
- _offText = offText;
-
- _offLabel.text = offText;
- }
- }
- - (void)setOnTintColor:(UIColor *)onTintColor
- {
- if (_onTintColor != onTintColor) {
- _onTintColor = onTintColor;
-
- _onContentView.backgroundColor = onTintColor;
- }
- }
- - (void)setTintColor:(UIColor *)tintColor
- {
- if (_tintColor != tintColor) {
- _tintColor = tintColor;
-
- _offContentView.backgroundColor = tintColor;
- }
- }
- - (void)setThumbTintColor:(UIColor *)thumbTintColor
- {
- if (_thumbTintColor != thumbTintColor) {
- _thumbTintColor = thumbTintColor;
-
- _knobView.backgroundColor = _thumbTintColor;
- }
- }
- - (void)layoutSubviews
- {
- [super layoutSubviews];
-
- self.containerView.frame = self.bounds;
-
- CGFloat r = CGRectGetHeight(self.containerView.bounds) / 2.0;
-
- self.containerView.layer.cornerRadius = r;
- self.containerView.layer.masksToBounds = YES;
-
- CGFloat margin = (CGRectGetHeight(self.bounds) - self.ballSize) / 2.0;
-
- if (!self.isOn) {
- // frame of off status
- self.onContentView.frame = CGRectMake(-1 * CGRectGetWidth(self.containerView.bounds),
- 0,
- CGRectGetWidth(self.containerView.bounds),
- CGRectGetHeight(self.containerView.bounds));
-
- self.offContentView.frame = CGRectMake(0,
- 0,
- CGRectGetWidth(self.containerView.bounds),
- CGRectGetHeight(self.containerView.bounds));
-
- self.knobView.frame = CGRectMake(margin,
- margin,
- self.ballSize,
- self.ballSize);
- } else {
- // frame of on status
- self.onContentView.frame = CGRectMake(0,
- 0,
- CGRectGetWidth(self.containerView.bounds),
- CGRectGetHeight(self.containerView.bounds));
-
- self.offContentView.frame = CGRectMake(0,
- CGRectGetWidth(self.containerView.bounds),
- CGRectGetWidth(self.containerView.bounds),
- CGRectGetHeight(self.containerView.bounds));
-
- self.knobView.frame = CGRectMake(CGRectGetWidth(self.containerView.bounds) - margin - self.ballSize,
- margin,
- self.ballSize,
- self.ballSize);
- }
-
- CGFloat lHeight = 20.0f;
- CGFloat lMargin = r - (sqrtf(powf(r, 2) - powf(lHeight / 2.0, 2))) + margin;
-
- self.onLabel.frame = CGRectMake(lMargin,
- r - lHeight / 2.0,
- CGRectGetWidth(self.onContentView.bounds) - lMargin - self.ballSize - 2 * margin,
- lHeight);
-
- self.offLabel.frame = CGRectMake(self.ballSize + 2 * margin,
- r - lHeight / 2.0,
- CGRectGetWidth(self.onContentView.bounds) - lMargin - self.ballSize - 2 * margin,
- lHeight);
- }
- - (void)setOn:(BOOL)on
- {
- [self setOn:on animated:NO];
- }
- - (void)setOn:(BOOL)on animated:(BOOL)animated
- {
- if (_on == on) {
- return;
- }
-
- _on = on;
-
- CGFloat margin = (CGRectGetHeight(self.bounds) - self.ballSize) / 2.0;
-
- if (!animated) {
- if (!self.isOn) {
- // frame of off status
- self.onContentView.frame = CGRectMake(-1 * CGRectGetWidth(self.containerView.bounds),
- 0,
- CGRectGetWidth(self.containerView.bounds),
- CGRectGetHeight(self.containerView.bounds));
-
- self.offContentView.frame = CGRectMake(0,
- 0,
- CGRectGetWidth(self.containerView.bounds),
- CGRectGetHeight(self.containerView.bounds));
-
- self.knobView.frame = CGRectMake(margin,
- margin,
- self.ballSize,
- self.ballSize);
- } else {
- // frame of on status
- self.onContentView.frame = CGRectMake(0,
- 0,
- CGRectGetWidth(self.containerView.bounds),
- CGRectGetHeight(self.containerView.bounds));
-
- self.offContentView.frame = CGRectMake(0,
- CGRectGetWidth(self.containerView.bounds),
- CGRectGetWidth(self.containerView.bounds),
- CGRectGetHeight(self.containerView.bounds));
-
- self.knobView.frame = CGRectMake(CGRectGetWidth(self.containerView.bounds) - margin - self.ballSize,
- margin,
- self.ballSize,
- self.ballSize);
- }
- } else {
- if (self.isOn) {
- [UIView animateWithDuration:0.25
- animations:^{
- self.knobView.frame = CGRectMake(CGRectGetWidth(self.containerView.bounds) - margin - self.ballSize,
- margin,
- self.ballSize,
- self.ballSize);
- }
- completion:^(BOOL finished){
- self.onContentView.frame = CGRectMake(0,
- 0,
- CGRectGetWidth(self.containerView.bounds),
- CGRectGetHeight(self.containerView.bounds));
-
- self.offContentView.frame = CGRectMake(0,
- CGRectGetWidth(self.containerView.bounds),
- CGRectGetWidth(self.containerView.bounds),
- CGRectGetHeight(self.containerView.bounds));
- }];
- } else {
- [UIView animateWithDuration:0.25
- animations:^{
- self.knobView.frame = CGRectMake(margin,
- margin,
- self.ballSize,
- self.ballSize);
- }
- completion:^(BOOL finished){
- self.onContentView.frame = CGRectMake(-1 * CGRectGetWidth(self.containerView.bounds),
- 0,
- CGRectGetWidth(self.containerView.bounds),
- CGRectGetHeight(self.containerView.bounds));
-
- self.offContentView.frame = CGRectMake(0,
- 0,
- CGRectGetWidth(self.containerView.bounds),
- CGRectGetHeight(self.containerView.bounds));
- }];
- }
- }
- [self sendActionsForControlEvents:UIControlEventValueChanged];
- }
- #pragma mark - Private API
- - (void)commonInit
- {
- self.backgroundColor = [UIColor clearColor];
-
- _onTintColor = self.onColor;
- _tintColor = self.offColor;
- _thumbTintColor = [UIColor colorWithWhite:1.0 alpha:1.0];
-
- _textFont = self.font;
- _textColor = [UIColor whiteColor];
-
- _containerView = [[UIView alloc] initWithFrame:self.bounds];
- _containerView.backgroundColor = [UIColor clearColor];
- _containerView.userInteractionEnabled = NO;
- [self addSubview:_containerView];
-
- _onContentView = [[UIView alloc] initWithFrame:self.bounds];
- _onContentView.backgroundColor = _onTintColor;
- [_containerView addSubview:_onContentView];
-
- _offContentView = [[UIView alloc] initWithFrame:self.bounds];
- _offContentView.backgroundColor = _tintColor;
- [_containerView addSubview:_offContentView];
-
- _knobView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.ballSize, self.ballSize)];
- _knobView.backgroundColor = _thumbTintColor;
- _knobView.layer.cornerRadius = self.ballSize / 2.0;
- _knobView.layer.shadowOffset = CGSizeMake(0,0.5);
- _knobView.layer.shadowColor = [UIColor blackColor].CGColor;
- _knobView.layer.shadowOpacity = 0.3f;
- [_containerView addSubview:_knobView];
-
- _onLabel = [[UILabel alloc] initWithFrame:CGRectZero];
- _onLabel.backgroundColor = [UIColor clearColor];
- _onLabel.textAlignment = NSTextAlignmentCenter;
- _onLabel.textColor = _textColor;
- _onLabel.font = _font;
- _onLabel.text = _onText;
- [_onContentView addSubview:_onLabel];
-
- _offLabel = [[UILabel alloc] initWithFrame:CGRectZero];
- _offLabel.backgroundColor = [UIColor clearColor];
- _offLabel.textAlignment = NSTextAlignmentCenter;
- _offLabel.textColor = _textColor;
- _offLabel.font = _font;
- _offLabel.text = _offText;
- [_offContentView addSubview:_offLabel];
-
- // UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self
- // action:@selector(handleTapTapGestureRecognizerEvent:)];
- // tapGesture.delegate = self;
- // [self addGestureRecognizer:tapGesture];
- UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self
- action:@selector(handlePanGestureRecognizerEvent:)];
- [self addGestureRecognizer:panGesture];
- }
- - (CGRect)roundRect:(CGRect)frameOrBounds
- {
- CGRect newRect = frameOrBounds;
-
- if (newRect.size.height > FUSwitchMaxHeight) {
- newRect.size.height = FUSwitchMaxHeight;
- }
-
- if (newRect.size.height < FUSwitchMinHeight) {
- newRect.size.height = FUSwitchMinHeight;
- }
-
- if (newRect.size.width < FUSwitchMinWidth) {
- newRect.size.width = FUSwitchMinWidth;
- }
-
- return newRect;
- }
- - (void)handleTapTapGestureRecognizerEvent:(UITapGestureRecognizer *)recognizer
- {
- if (recognizer.state == UIGestureRecognizerStateEnded) {
- [self setOn:!self.isOn animated:NO];
- }
- }
- - (void)handlePanGestureRecognizerEvent:(UIPanGestureRecognizer *)recognizer
- {
- CGFloat margin = (CGRectGetHeight(self.bounds) - self.ballSize) / 2.0;
- CGFloat offset = 6.0f;
-
- switch (recognizer.state) {
- case UIGestureRecognizerStateBegan:{
- if (!self.isOn) {
- [UIView animateWithDuration:0.25
- animations:^{
- self.knobView.frame = CGRectMake(margin,
- margin,
- self.ballSize + offset,
- self.ballSize);
- }];
- } else {
- [UIView animateWithDuration:0.25
- animations:^{
- self.knobView.frame = CGRectMake(CGRectGetWidth(self.containerView.bounds) - margin - (self.ballSize + offset),
- margin,
- self.ballSize + offset,
- self.ballSize);
- }];
- }
- break;
- }
- case UIGestureRecognizerStateCancelled:
- case UIGestureRecognizerStateFailed: {
- if (!self.isOn) {
- [UIView animateWithDuration:0.25
- animations:^{
- self.knobView.frame = CGRectMake(margin,
- margin,
- self.ballSize,
- self.ballSize);
- }];
- } else {
- [UIView animateWithDuration:0.25
- animations:^{
- self.knobView.frame = CGRectMake(CGRectGetWidth(self.containerView.bounds) - self.ballSize,
- margin,
- self.ballSize,
- self.ballSize);
- }];
- }
- break;
- }
- case UIGestureRecognizerStateChanged:{
- break;
- }
- case UIGestureRecognizerStateEnded:
- [self setOn:!self.isOn animated:YES];
- break;
- case UIGestureRecognizerStatePossible:
- break;
- }
- }
- -(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
- [super touchesEnded:touches withEvent:event];
- [self setOn:!self.isOn animated:YES];
- }
- /*
- // Only override drawRect: if you perform custom drawing.
- // An empty implementation adversely affects performance during animation.
- - (void)drawRect:(CGRect)rect {
- // Drawing code
- }
- */
- @end
|