用动画切换按钮的状态
效果
源码
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:NSInternalInconsistencyException format:@"对不起,您不能直接调用 '%@ %d' 中的方法 '%@',您需要通过继承其子类,在子类中重载该方法", [NSString stringWithUTF8String:__FILE__].lastPathComponent, __LINE__, NSStringFromSelector(_cmd)]; } - (void)touchDragExit { [NSException raise:NSInternalInconsistencyException format:@"对不起,您不能直接调用 '%@ %d' 中的方法 '%@',您需要通过继承其子类,在子类中重载该方法", [NSString stringWithUTF8String:__FILE__].lastPathComponent, __LINE__, NSStringFromSelector(_cmd)]; } - (void)touchBegin { [NSException raise:NSInternalInconsistencyException format:@"对不起,您不能直接调用 '%@ %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; // 背景view self.backgroundView = [[UIView alloc] initWithFrame:self.bounds]; self.backgroundView.backgroundColor = [UIColor clearColor]; [self addSubview:self.backgroundView]; // Label self.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]; // backgroundView self.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
核心