用动画切换按钮的状态
效果
源码
//// BaseControl.h// BaseButton//// Created by YouXianMing on 15/8/27.// Copyright (c) 2015年 YouXianMing. All rights reserved.//#import@class BaseControl;@protocol BaseControlDelegate @optional/** * 点击事件触发 * * @param control BaseControl对象 */- (void)baseControlTouchEvent:(BaseControl *)control;@end@interface BaseControl : UIView/** * 代理方法 */@property (nonatomic, weak) id 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
核心