用动画切换按钮的状态
效果
源码
https://github.com/YouXianMing/UI-Component-Collection
// // BaseControl.h // BaseButton // // Created by YouXianMing on 15/8/27. // Copyright (c) 2015年 YouXianMing. All rights reserved. // #import <UIKit/UIKit.h> @class BaseControl;@protocol BaseControlDelegate <NSObject>@optional/*** 点击事件触发** @param control BaseControl对象*/ - (void)baseControlTouchEvent:(BaseControl *)control;@end@interface BaseControl : UIView/*** 代理方法*/ @property (nonatomic, weak) id <BaseControlDelegate> delegate;#pragma mark - 以下方法需要子类重载/*** 触发了点击事件*/ - (void)touchEvent;/*** 拖拽到rect外面触发的事件*/ - (void)touchDragExit;/*** 点击事件开始*/ - (void)touchBegin;@end
// // BaseControl.m // BaseButton // // Created by YouXianMing on 15/8/27. // Copyright (c) 2015年 YouXianMing. All rights reserved. // #import "BaseControl.h"@interface BaseControl ()@property (nonatomic, strong) UIButton *button;@end@implementation BaseControl- (instancetype)initWithFrame:(CGRect)frame {if (self = [super initWithFrame:frame]) {[self baseControlSetup];}return self; }- (void)baseControlSetup {_button = [[UIButton alloc] initWithFrame:self.bounds];[self addSubview:_button];// 开始点击[_button addTarget:self action:@selector(touchBegin) forControlEvents:UIControlEventTouchDown | UIControlEventTouchDragEnter];// 拖拽到rect外面[_button addTarget:self action:@selector(touchDragExit) forControlEvents:UIControlEventTouchDragExit | UIControlEventTouchCancel];// 触发事件 [_button addTarget:self action:@selector(touchEvent) forControlEvents:UIControlEventTouchUpInside]; }- (void)touchEvent {[NSException raise:NSInternalInconsistencyExceptionformat:@"对不起,您不能直接调用 '%@ %d' 中的方法 '%@',您需要通过继承其子类,在子类中重载该方法",[NSString stringWithUTF8String:__FILE__].lastPathComponent, __LINE__, NSStringFromSelector(_cmd)]; }- (void)touchDragExit {[NSException raise:NSInternalInconsistencyExceptionformat:@"对不起,您不能直接调用 '%@ %d' 中的方法 '%@',您需要通过继承其子类,在子类中重载该方法",[NSString stringWithUTF8String:__FILE__].lastPathComponent, __LINE__, NSStringFromSelector(_cmd)]; }- (void)touchBegin {[NSException raise:NSInternalInconsistencyExceptionformat:@"对不起,您不能直接调用 '%@ %d' 中的方法 '%@',您需要通过继承其子类,在子类中重载该方法",[NSString stringWithUTF8String:__FILE__].lastPathComponent, __LINE__, NSStringFromSelector(_cmd)]; }@end
// // CustomButton.h // CustomButton // // Created by YouXianMing on 16/5/21. // Copyright © 2016年 YouXianMing. All rights reserved. // #import "BaseControl.h"typedef NS_OPTIONS(NSUInteger, BaseControlState) {BaseControlStateNormal = 1000,BaseControlStateHighlighted,BaseControlStateDisabled, };@interface CustomButton : BaseControl/*** 目标*/ @property (nonatomic, weak) id target;/*** 按钮事件*/ @property (nonatomic) SEL buttonEvent;/*** 普通背景色*/ @property (nonatomic, strong) UIColor *normalBackgroundColor;/*** 高亮状态背景色*/ @property (nonatomic, strong) UIColor *highlightBackgroundColor;/*** 禁用状态背景色*/ @property (nonatomic, strong) UIColor *disabledBackgroundColor;/*** 状态值*/ @property (nonatomic, readonly) BaseControlState state;/*** 按钮标题*/ @property (nonatomic, strong) NSString *title;/*** 字体*/ @property (nonatomic, strong) UIFont *font;/*** 水平位移*/ @property (nonatomic) CGFloat horizontalOffset;/*** 垂直位移*/ @property (nonatomic) CGFloat verticalOffset;/*** 对其方式*/ @property (nonatomic) NSTextAlignment textAlignment;/*** 给标题设置颜色** @param color 颜色* @param state 状态*/ - (void)setTitleColor:(UIColor *)color state:(BaseControlState)state;/*** 切换到不同的状态** @param state 状态* @param animated 是否执行动画*/ - (void)changeToState:(BaseControlState)state animated:(BOOL)animated;@end
// // CustomButton.m // CustomButton // // Created by YouXianMing on 16/5/21. // Copyright © 2016年 YouXianMing. All rights reserved. // #import "CustomButton.h"@interface CustomButton ()@property (nonatomic) BaseControlState state; @property (nonatomic) BOOL enableEvent; @property (nonatomic, strong) UILabel *normalLabel; @property (nonatomic, strong) UILabel *highlightedLabel; @property (nonatomic, strong) UILabel *disabledLabel; @property (nonatomic, strong) UIView *backgroundView;@end@implementation CustomButton- (instancetype)initWithFrame:(CGRect)frame {if (self = [super initWithFrame:frame]) {// 激活_enableEvent = YES;// 背景viewself.backgroundView = [[UIView alloc] initWithFrame:self.bounds];self.backgroundView.backgroundColor = [UIColor clearColor];[self addSubview:self.backgroundView];// Labelself.normalLabel = [[UILabel alloc] initWithFrame:self.bounds];self.normalLabel.textAlignment = NSTextAlignmentCenter;self.normalLabel.textColor = [UIColor clearColor];[self addSubview:self.normalLabel];self.highlightedLabel = [[UILabel alloc] initWithFrame:self.bounds];self.highlightedLabel.textAlignment = NSTextAlignmentCenter;self.highlightedLabel.textColor = [UIColor clearColor];[self addSubview:self.highlightedLabel];self.disabledLabel = [[UILabel alloc] initWithFrame:self.bounds];self.disabledLabel.textAlignment = NSTextAlignmentCenter;self.disabledLabel.textColor = [UIColor clearColor];[self addSubview:self.disabledLabel];// backgroundViewself.backgroundView.userInteractionEnabled = NO;self.normalLabel.userInteractionEnabled = NO;self.highlightedLabel.userInteractionEnabled = NO;self.disabledLabel.userInteractionEnabled = NO;}return self; }- (void)setTitleColor:(UIColor *)color state:(BaseControlState)state {if (state == BaseControlStateNormal) {self.normalLabel.textColor = color;} else if (state == BaseControlStateHighlighted) {self.highlightedLabel.textColor = color;} else if (state == BaseControlStateDisabled) {self.disabledLabel.textColor = color;} }#pragma mark - 重载的方法- (void)touchEvent {if (_enableEvent == NO) {return;}[self changeToState:BaseControlStateNormal animated:YES];if (self.delegate && [self.delegate respondsToSelector:@selector(baseControlTouchEvent:)]) {[self.delegate baseControlTouchEvent:self];}if (self.buttonEvent && self.target) {#pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks"[self.target performSelector:self.buttonEvent withObject:self]; #pragma clang diagnostic pop} }- (void)touchDragExit {if (_enableEvent == NO) {return;}[self changeToState:BaseControlStateNormal animated:YES]; }- (void)touchBegin {if (_enableEvent == NO) {return;}[self changeToState:BaseControlStateHighlighted animated:YES]; }#pragma mark -- (void)changeToState:(BaseControlState)state animated:(BOOL)animated {_state = state;if (state == BaseControlStateNormal) {_enableEvent = YES;[self normalStateAnimated:animated];} else if (state == BaseControlStateHighlighted) {_enableEvent = YES;[self highlightedAnimated:animated];} else if (state == BaseControlStateDisabled) {_enableEvent = NO;[self disabledAnimated:animated];} }- (void)normalStateAnimated:(BOOL)animated {if (!animated) {self.normalLabel.alpha = 1.f;self.highlightedLabel.alpha = 0.f;self.disabledLabel.alpha = 0.f;self.backgroundView.backgroundColor = self.normalBackgroundColor;} else {[UIView animateWithDuration:0.25f delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{self.normalLabel.alpha = 1.f;self.highlightedLabel.alpha = 0.f;self.disabledLabel.alpha = 0.f;self.backgroundView.backgroundColor = self.normalBackgroundColor;} completion:nil];} }- (void)highlightedAnimated:(BOOL)animated {if (!animated) {self.normalLabel.alpha = 0.f;self.highlightedLabel.alpha = 1.f;self.disabledLabel.alpha = 0.f;self.backgroundView.backgroundColor = self.highlightBackgroundColor;} else {[UIView animateWithDuration:0.25f delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{self.normalLabel.alpha = 0.f;self.highlightedLabel.alpha = 1.f;self.disabledLabel.alpha = 0.f;self.backgroundView.backgroundColor = self.highlightBackgroundColor;} completion:nil];} }- (void)disabledAnimated:(BOOL)animated {if (!animated) {self.normalLabel.alpha = 0.f;self.highlightedLabel.alpha = 0.f;self.disabledLabel.alpha = 1.f;self.backgroundView.backgroundColor = self.disabledBackgroundColor;} else {[UIView animateWithDuration:0.25f delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{self.normalLabel.alpha = 0.f;self.highlightedLabel.alpha = 0.f;self.disabledLabel.alpha = 1.f;self.backgroundView.backgroundColor = self.disabledBackgroundColor;} completion:nil];} }#pragma mark - 重写getter,setter方法- (void)setTitle:(NSString *)title {_title = title;self.normalLabel.text = title;self.highlightedLabel.text = title;self.disabledLabel.text = title; }- (void)setTextAlignment:(NSTextAlignment)textAlignment {_textAlignment = textAlignment;self.normalLabel.textAlignment = textAlignment;self.highlightedLabel.textAlignment = textAlignment;self.disabledLabel.textAlignment = textAlignment; }- (void)setFont:(UIFont *)font {_font = font;self.normalLabel.font = font;self.highlightedLabel.font = font;self.disabledLabel.font = font; }- (void)setVerticalOffset:(CGFloat)verticalOffset {_verticalOffset = verticalOffset;CGRect frame = self.normalLabel.frame;frame.origin.x = verticalOffset;self.normalLabel.frame = frame;self.highlightedLabel.frame = frame;self.disabledLabel.frame = frame; }- (void)setHorizontalOffset:(CGFloat)horizontalOffset {_horizontalOffset = horizontalOffset;CGRect frame = self.normalLabel.frame;frame.origin.y = horizontalOffset;self.normalLabel.frame = frame;self.highlightedLabel.frame = frame;self.disabledLabel.frame = frame; }@end
控制器源码
// // ViewController.m // CustomButton // // Created by YouXianMing on 16/5/21. // Copyright © 2016年 YouXianMing. All rights reserved. // #import "ViewController.h" #import "CustomButton.h" #import "UIView+SetRect.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];{CustomButton *button = [[CustomButton alloc] initWithFrame:CGRectMake(0, 0, 200, 40.f)];button.title = @"Heiti TC";button.center = self.view.center;button.y -= 100;button.font = [UIFont fontWithName:@"Heiti TC" size:16.f];button.layer.borderWidth = 0.5f;button.layer.borderColor = [UIColor blackColor].CGColor;button.layer.cornerRadius = 4.f;button.layer.masksToBounds = YES;button.buttonEvent = @selector(buttonsEvent:);button.target = self;button.normalBackgroundColor = [UIColor blackColor];button.highlightBackgroundColor = [UIColor whiteColor];button.disabledBackgroundColor = [UIColor grayColor];[button setTitleColor:[UIColor whiteColor] state:BaseControlStateNormal];[button setTitleColor:[UIColor blackColor] state:BaseControlStateHighlighted];[button setTitleColor:[UIColor whiteColor] state:BaseControlStateDisabled];[self.view addSubview:button];[button changeToState:BaseControlStateNormal animated:NO];}{CustomButton *button = [[CustomButton alloc] initWithFrame:CGRectMake(0, 0, 200, 40.f)];button.title = @"Heiti TC";button.tag = 2;button.center = self.view.center;button.y += 100;button.font = [UIFont fontWithName:@"Heiti TC" size:16.f];button.layer.borderWidth = 0.5f;button.layer.borderColor = [UIColor orangeColor].CGColor;button.layer.cornerRadius = 4.f;button.layer.masksToBounds = YES;button.buttonEvent = @selector(buttonsEvent:);button.target = self;button.normalBackgroundColor = [[UIColor orangeColor] colorWithAlphaComponent:0.95f];button.highlightBackgroundColor = [[UIColor orangeColor] colorWithAlphaComponent:0.65f];button.disabledBackgroundColor = [[UIColor orangeColor] colorWithAlphaComponent:0.45f];[button setTitleColor:[UIColor whiteColor] state:BaseControlStateNormal];[button setTitleColor:[UIColor whiteColor] state:BaseControlStateHighlighted];[button setTitleColor:[[UIColor whiteColor] colorWithAlphaComponent:0.75f] state:BaseControlStateDisabled];[self.view addSubview:button];[button changeToState:BaseControlStateNormal animated:NO];} }- (void)buttonsEvent:(CustomButton *)button {NSLog(@"%@", button);if (button.tag == 2) {static int i = 0;if (i++ >= 3) {[button changeToState:BaseControlStateDisabled animated:YES];[self performSelector:@selector(changeTitle:) withObject:button afterDelay:0.15f];}} }- (void)changeTitle:(CustomButton *)button {button.title = @"DisabledState"; }@end
核心