点击按钮的同时为了是用户更加直接的看到正在执行的进度的变化或者正在执行的进程的状态,通常会在按钮上添加一个活动指示器来告诉用户
但是为了不影响UIbutton的使用可以使用类别增加方法属性
#import <UIKit/UIKit.h>
typedef enum : NSInteger {
UIButtonIndicatorAnimationTypeDefault,
UIButtonIndicatorAnimationTypeRound,
} UIButtonIndicatorAnimationType;
typedef enum : NSInteger {
UIButtonIndicatorPositionRight, // default
UIButtonIndicatorPositionCenter,
UIButtonIndicatorPositionLeft
} UIButtonIndicatorPosition;
@interface UIButton (Indicator)
/// 可用 default round, 默认是系统的indicator,
@property(nonatomic,assign)UIButtonIndicatorAnimationType kk_animationType;
/// 可用 right,center,left
@property(nonatomic,assign)UIButtonIndicatorPosition kk_position;
// 相对于titleLable 右侧/左侧偏移量 默认 10
@property(nonatomic,assign)NSNumber * kk_xOffset;
/// 默认 0
@property(nonatomic,assign)NSNumber * kk_yOffset;
/// 默认1
@property(nonatomic,assign)NSNumber * kk_zoomScale;
/// 是否是正在动画
@property(nonatomic,assign)BOOL kk_animating;
/// 当使用默认的动画类型。动画图为 UIActivityIndicatorView
@property(nonatomic,strong,readonly)UIActivityIndicatorView * indicatorView;
-(void)startIndicatorAnimation;
-(void)stopIndicatorAnimation;
-(void)startIndicatorAnimation:(void(^)())didBegin;
-(void)stopIndicatorAnimationCompletion:(void(^)())completion;
@end
#import "UIButton+Indicator.h"
#import <objc/runtime.h>
@interface UIButton (KKIndictorTitles)
// 保存之前的titles
@property(nonatomic,strong)NSMutableDictionary * dicTitles;
@end
@implementation UIButton (KKIndictorTitles)
-(void)setDicTitles:(NSMutableDictionary *)dicTitles{
objc_setAssociatedObject(self, @"dicTitles", dicTitles, OBJC_ASSOCIATION_RETAIN);
}
-(NSMutableDictionary *)dicTitles{
NSMutableDictionary * dic = objc_getAssociatedObject(self, @"dicTitles");
if (!dic) {
dic = [[NSMutableDictionary alloc]init];
self.dicTitles = dic;
}
return dic;
}
@end
@implementation UIButton (Indicator)
-(void)getNeedSaveSatte:(NSArray**)state keys:(NSArray**)keys{
if (state) {
*state = @[
@(UIControlStateNormal),
@(UIControlStateSelected),
@(UIControlStateHighlighted),
@(UIControlStateDisabled)
];
}
if (!keys) {
return;
}
*keys = @[
@"normal",
@"seleted",
@"high",
@"disable"
];
}
-(void)savaCurrenTitles{
NSArray * arr ;
NSArray * arrName ;
[self getNeedSaveSatte:&arr keys:&arrName];
NSString * tmp ;
for (int i = 0; i < arr.count ; i++) {
NSNumber * num = arr[i];
tmp = [self titleForState:num.integerValue];
if (tmp) {
[self.dicTitles setValue:tmp forKey:arrName[i]];
}else{
[self.dicTitles setNilValueForKey:arr[i]];
}
}
}
-(void)setNILForAllState{
NSArray * state ;
[self getNeedSaveSatte:&state keys:nil];
for (NSNumber * num in state) {
[self setTitle:nil forState:num.integerValue];
}
}
-(void)startIndicatorAnimation{
[self startIndicatorAnimation:nil];
}
-(void)startIndicatorAnimation:(void(^)())didBegin{
if (self.kk_animating) {
return;
}
// 保存当前状态
if (self.kk_position == UIButtonIndicatorPositionCenter) {
[self savaCurrenTitles];
}
// 初始化数据
[self initData];
if (self.kk_animationType == UIButtonIndicatorAnimationTypeDefault) {
[self setDefaultTypeViews:didBegin];
}
}
-(void)setDefaultTypeViews:(void(^)())didBegin{
if (self.indicatorView) {
self.indicatorView.transform = CGAffineTransformIdentity;
CGSize indiSize = self.indicatorView.bounds.size;
CGRect titleFrame = self.titleLabel.frame;
self.indicatorView.transform = CGAffineTransformMakeScale(self.kk_zoomScale.floatValue, self.kk_zoomScale.floatValue);
// size after deal
CGSize size = CGSizeMake(indiSize.width, indiSize.height);
// deal for center
CGPoint newCenter;
if (self.kk_position == UIButtonIndicatorPositionRight) {
newCenter = CGPointMake(CGRectGetMaxX(titleFrame) + self.kk_xOffset.floatValue + size.width / 2.0,
CGRectGetMidY(self.bounds) + self.kk_yOffset.floatValue);
}else if (self.kk_position == UIButtonIndicatorPositionCenter){
[self setNILForAllState];
newCenter = CGPointMake(CGRectGetMidX(self.bounds) + self.kk_xOffset.floatValue,
CGRectGetMidY(self.bounds) + self.kk_yOffset.floatValue);
}else{
newCenter = CGPointMake(CGRectGetMinX(titleFrame) + self.kk_xOffset.floatValue - size.width / 2.0,
CGRectGetMidY(self.bounds) + self.kk_yOffset.floatValue);
}
dispatch_async(dispatch_get_main_queue(), ^{
if (![self.subviews containsObject:self.indicatorView]) {
[self addSubview:self.indicatorView];
}
self.indicatorView.bounds = CGRectMake(0, 0, size.width, size.height);
self.indicatorView.center = newCenter;
});
self.kk_animating = YES;
[self.indicatorView startAnimating];
if (didBegin) {
didBegin();
}
}
}
-(void)initData{
switch (self.kk_position) {
case UIButtonIndicatorPositionLeft:
self.kk_xOffset = (self.kk_xOffset)?:@(-10);
break;
case UIButtonIndicatorPositionRight:
self.kk_xOffset = (self.kk_xOffset)?:@(10);
break;
default:
self.kk_xOffset = (self.kk_xOffset)?:@(0);
break;
}
if (!self.kk_zoomScale) {
self.kk_zoomScale = @(1);
}
}
-(void)stopIndicatorAnimation{
[self stopIndicatorAnimationCompletion:nil];
}
-(void)stopIndicatorAnimationCompletion:(void(^)())completion{
if (!self.kk_animating) {
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
if (self.kk_animationType == UIButtonIndicatorAnimationTypeDefault && self.indicatorView) {
[self.indicatorView stopAnimating];
}
[self reBackData];
self.kk_animating = NO;
[self invilateData];
if (completion) {
completion();
}
});
}
-(void)reBackData{
NSArray * arr ;
NSArray * arrName ;
[self getNeedSaveSatte:&arr keys:&arrName];
NSString * tmp ;
for (int i = 0; i < arr.count ; i++) {
tmp = [self.dicTitles valueForKey:arrName[i]];
if (tmp) {
[self setTitle:tmp forState:[arr[i] integerValue]];
}
}
}
-(void)invilateData{
[self.dicTitles removeAllObjects];
self.dicTitles = nil;
self.kk_xOffset = nil;
self.kk_yOffset = nil;
self.kk_zoomScale = nil;
[self.indicatorView removeFromSuperview];
}
-(UIActivityIndicatorView *)indicatorView{
if (!objc_getAssociatedObject(self, @"indicatorView")) {
UIActivityIndicatorView * indicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
indicator.hidesWhenStopped = YES;
objc_setAssociatedObject(self, @"indicatorView", indicator, OBJC_ASSOCIATION_RETAIN);
}
return objc_getAssociatedObject(self, @"indicatorView");
}
-(void)setKk_animationType:(UIButtonIndicatorAnimationType)kk_animationType{
objc_setAssociatedObject(self, @"kk_animationType", @(kk_animationType), OBJC_ASSOCIATION_COPY);
}
-(UIButtonIndicatorAnimationType)kk_animationType{
NSNumber * num = objc_getAssociatedObject(self, @"kk_animationType");
if (!num) {
num = @(UIButtonIndicatorAnimationTypeDefault);
}
return [num integerValue];
}
-(void)setKk_position:(UIButtonIndicatorPosition)kk_position{
objc_setAssociatedObject(self, @"kk_position", @(kk_position), OBJC_ASSOCIATION_COPY);
}
-(UIButtonIndicatorPosition)kk_position{
NSNumber * num = objc_getAssociatedObject(self, @"kk_position");
if (!num) {
num = @(UIButtonIndicatorPositionRight);
}
return num.integerValue;
}
-(void)setKk_xOffset:(NSNumber*)kk_xOffset{
objc_setAssociatedObject(self, @"kk_xOffset", kk_xOffset, OBJC_ASSOCIATION_COPY);
}
-(NSNumber*)kk_xOffset{
return objc_getAssociatedObject(self, @"kk_xOffset");
}
-(void)setKk_yOffset:(NSNumber*)kk_yOffset{
objc_setAssociatedObject(self, @"kk_yOffset", kk_yOffset, OBJC_ASSOCIATION_COPY);
}
-(NSNumber*)kk_yOffset{
return objc_getAssociatedObject(self, @"kk_yOffset");
}
-(void)setKk_zoomScale:(NSNumber*)kk_zoomScale{
objc_setAssociatedObject(self, @"kk_zoomScale", kk_zoomScale, OBJC_ASSOCIATION_COPY);
}
-(NSNumber*)kk_zoomScale{
return objc_getAssociatedObject(self, @"kk_zoomScale");
}
-(void)setKk_animating:(BOOL)kk_animating{
objc_setAssociatedObject(self, @"kk_animating", @(kk_animating), OBJC_ASSOCIATION_COPY);
}
-(BOOL)kk_animating{
return [objc_getAssociatedObject(self, @"kk_animating") boolValue];
}
@end