// // GMButton.m // Gengmei // // Created by Thierry on 12/26/14. // Copyright (c) 2014 Wanmeichuangyi. All rights reserved. // #import "GMButton.h" #import "GMFont.h" #import #import #import "UIImage+GM.h" @interface GMButton () @property (nonatomic, strong) UIColor *highlightBackgroundColor; @property (nonatomic, strong) UIColor *normalBackgroundColor; @property (nonatomic, strong) UIColor *selectedBackgroundColor; @property (nonatomic, strong) UIColor *disableBackgroundColor; @property (nonatomic, assign) GMButtonType customType; @property (nonatomic, strong) UIColor *normalBorderColor; @property (nonatomic, strong) UIColor *disableBorderColor; @property (nonatomic, strong) NSArray *normalGradientColors; @property (nonatomic, strong) NSArray *highlightGradientColors; @end @implementation GMButton #pragma mark - 初始化 -(id)init{ self = [super init]; if (self) { [self setup]; } return self; } - (id)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { [self setup]; } return self; } - (void)awakeFromNib{ [super awakeFromNib]; [self setup]; } - (void)setup{ _adaptiveHotAreaWidth = 44.0; _adaptiveHotAreaHeight = 44.0; _normalBackgroundColor = [UIColor clearColor]; } #pragma mark - 实例化方法 + (instancetype)buttonWithTitle:(NSString *)title backgroundColor:(UIColor *)bgColor titleFontSize:(CGFloat)size titleColor:(UIColor *)titleColor{ GMButton *button = [GMButton buttonWithType:UIButtonTypeCustom]; if (bgColor) { button.backgroundColor = bgColor; } if (title) { [button setTitle:title forState:UIControlStateNormal]; } button.titleLabel.font = [UIFont gmFont:size ?: 14]; if (titleColor) { [button setTitleColor:titleColor forState:UIControlStateNormal]; } return button; } + (instancetype)buttonWithCustomType:(GMButtonType)customType{ GMButton *button = [GMButton buttonWithType:UIButtonTypeCustom]; button.clipsToBounds = YES; button.customType = customType; [button setTitle:@"按钮" forState:UIControlStateNormal]; switch (customType) { case GMButtonTypeGreen: [button setGreenAppearance]; break; case GMButtonTypeGreenRoundCorner: button.layer.cornerRadius = 6 * ONE_PIXEL; [button setGreenAppearance]; break; case GMButtonTypeGreenSemicircle: [button setGreenAppearance]; break; case GMButtonTypeGreenRoundCornerBorder: button.layer.borderWidth = ONE_PIXEL; button.layer.cornerRadius = 6 * ONE_PIXEL; button.normalBorderColor = UIColor.mainVisual; button.disableBorderColor = UIColor.disable; [button setTitleColor:UIColor.mainVisual forState:UIControlStateNormal]; [button setBackgroundColor: UIColor.clearColor forState:UIControlStateNormal | UIControlStateDisabled]; button.enabled = YES; break; case GMButtonTypeGreenRoundCornerGradient: button.layer.cornerRadius = 6 * ONE_PIXEL; break; case GMButtonTypeGreenSemicircleGradient: break; case GMButtonTypeRed: [button setRedAppearance]; break; case GMButtonTypeRedRoundCorner: [button setRedAppearance]; button.layer.cornerRadius = 6 * ONE_PIXEL; break; case GMButtonTypeRedSemicircle: [button setRedAppearance]; break; case GMButtonTypeRedRoundCornerBorder: button.layer.borderWidth = ONE_PIXEL; button.layer.cornerRadius = 6 * ONE_PIXEL; button.normalBorderColor = UIColor.secondaryVisual; button.disableBorderColor = UIColor.disable; [button setBackgroundColor: UIColor.whiteColor forState:UIControlStateNormal | UIControlStateDisabled]; [button setTitleColor:UIColor.secondaryVisual forState:UIControlStateNormal]; button.enabled = YES; break; case GMButtonTypeRedRoundCornerGradient: button.layer.cornerRadius = 6 * ONE_PIXEL; break; case GMButtonTypeRedSemicircleGradient: break; case GMButtonTypeGraySemicircleBorder: button.layer.borderColor = UIColor.separatorLine.CGColor; button.layer.borderWidth = ONE_PIXEL; [button setBackgroundColor: UIColor.background forState:UIControlStateNormal]; [button setBackgroundColor: UIColor.separatorLine forState:UIControlStateHighlighted]; [button setTitleColor:UIColor.bodyText forState:UIControlStateNormal]; break; default: break; } return button; } //为半圆的设置半径 - (void)layoutSubviews{ [super layoutSubviews]; if (_customType == GMButtonTypeGreenSemicircle || _customType == GMButtonTypeGreenSemicircleBorder || _customType == GMButtonTypeGreenSemicircleGradient || _customType == GMButtonTypeRedSemicircle || _customType == GMButtonTypeRedSemicircleGradient || _customType == GMButtonTypeGraySemicircleBorder) { self.layer.cornerRadius = MIN(self.frame.size.height, self.frame.size.width)/2; } } #pragma mark - Button Appearance - (void)setGreenAppearance{ [self setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; [self setBackgroundColor:UIColor.buttonNormalGreen forState:UIControlStateNormal]; [self setBackgroundColor:UIColor.buttonHighlightGreen forState:UIControlStateHighlighted]; [self setBackgroundColor:UIColor.disable forState:UIControlStateDisabled]; } - (void)setRedAppearance{ [self setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; [self setBackgroundColor:UIColor.buttonNormalRed forState:UIControlStateNormal]; [self setBackgroundColor:UIColor.buttonHighlightRed forState:UIControlStateHighlighted]; [self setBackgroundColor:UIColor.disable forState:UIControlStateDisabled]; } #pragma mark - Gradient Color - (void)drawRect:(CGRect)rect{ [super drawRect:rect]; switch (_customType) { case GMButtonTypeGreenRoundCornerGradient: _normalGradientColors = @[[UIColor colorWithHex:0x7eefd4],[UIColor colorWithHex:0x66ceff]]; _highlightGradientColors = @[[UIColor colorWithHex:0x34d1c5],[UIColor colorWithHex:0x45BCCF]]; [self setGradientBackgroundColor]; break; case GMButtonTypeGreenSemicircleGradient: _normalGradientColors = @[[UIColor colorWithHex:0x45E7DE],[UIColor colorWithHex:0x58CBEF]]; _highlightGradientColors = @[[UIColor colorWithHex:0x2ECCC4],[UIColor colorWithHex:0x42B8DD]]; [self setGradientBackgroundColor]; break; case GMButtonTypeRedRoundCornerGradient: case GMButtonTypeRedSemicircleGradient: _normalGradientColors = @[[UIColor colorWithHex:0xFF6080],[UIColor colorWithHex:0xFA5D66]]; _highlightGradientColors = @[[UIColor colorWithHex:0xE45B7C],[UIColor colorWithHex:0xDE525B]]; [self setGradientBackgroundColor]; break; default: break; } } - (UIImage *)gradientColorImageFromColors:(NSArray*)colors gradientType:(GMGradientType)gradientType{ NSMutableArray *ar = [NSMutableArray array]; for(UIColor *c in colors) { [ar addObject:(id)c.CGColor]; } UIGraphicsBeginImageContextWithOptions(self.frame.size, YES, 1); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSaveGState(context); CGColorSpaceRef colorSpace = CGColorGetColorSpace([[colors lastObject] CGColor]); CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)ar, NULL); CGPoint start; CGPoint end; switch (gradientType) { case GMGradientTypeTopToBottom: start = CGPointMake(0.0, 0.0); end = CGPointMake(0.0,self.frame.size.height); break; case GMGradientTypeLeftToRight: start = CGPointMake(0.0, 0.0); end = CGPointMake(self.frame.size.width, 0.0); break; case GMGradientTypeLeftUpToRightLow: start = CGPointMake(0.0, 0.0); end = CGPointMake(self.frame.size.width, self.frame.size.height); break; case GMGradientTypeRightUpToLeftLow: start = CGPointMake(self.frame.size.width, 0.0); end = CGPointMake(0.0, self.frame.size.height); break; default: break; } CGContextDrawLinearGradient(context, gradient, start, end, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); CGGradientRelease(gradient); CGContextRestoreGState(context); CGColorSpaceRelease(colorSpace); UIGraphicsEndImageContext(); return image; } - (void)setGradientBackgroundColor{ UIImage *normalImage = [self gradientColorImageFromColors:_normalGradientColors gradientType:GMGradientTypeLeftUpToRightLow]; UIImage *highlightImage = [self gradientColorImageFromColors:_highlightGradientColors gradientType:GMGradientTypeLeftUpToRightLow]; [self setBackgroundImage:normalImage forState:UIControlStateNormal]; [self setBackgroundImage:highlightImage forState:UIControlStateHighlighted]; [self setBackgroundImage:[UIImage imageWithColor:UIColor.disable] forState:UIControlStateDisabled]; [self setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; } #pragma mark - Background Color - (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state{ if (state == UIControlStateNormal) { _normalBackgroundColor = backgroundColor; [self setBackgroundColor:_normalBackgroundColor]; }else if (state == UIControlStateHighlighted){ _highlightBackgroundColor = backgroundColor; }else if (state == UIControlStateSelected){ _selectedBackgroundColor = backgroundColor; }else if (state == UIControlStateDisabled) { _disableBackgroundColor = backgroundColor; } } #pragma mark - Setter - (void)setHighlighted:(BOOL)highlighted{ [super setHighlighted:highlighted]; if (_highlightBackgroundColor && highlighted) { self.backgroundColor = _highlightBackgroundColor; }else{ if (self.selected && _selectedBackgroundColor) { self.backgroundColor = _selectedBackgroundColor; }else{ self.backgroundColor = _normalBackgroundColor; } } } - (void)setSelected:(BOOL)selected{ [super setSelected:selected]; if (_selectedBackgroundColor && selected) { self.backgroundColor = _selectedBackgroundColor; }else{ self.backgroundColor = _normalBackgroundColor; } } - (void)setBackgroundColor:(UIColor *)backgroundColor{ [super setBackgroundColor:backgroundColor]; // 容错处理,只在为normal状态,才设置_normalBackgroundColor。 // 比如在controller里只调用了setBackgroundColor,为了保证在normal时回复到normal颜色,必须设置好_normalBackgroundColor if(self.state == UIControlStateNormal){ _normalBackgroundColor = backgroundColor; } } - (void)setEnabled:(BOOL)enabled{ [super setEnabled:enabled]; if (enabled){ self.backgroundColor = _normalBackgroundColor; switch (_customType) { case GMButtonTypeGreenSemicircleBorder: case GMButtonTypeGreenRoundCornerBorder: case GMButtonTypeGraySemicircleBorder: case GMButtonTypeRedRoundCornerBorder: self.layer.borderColor = _normalBorderColor.CGColor; break; default: break; } }else{ self.backgroundColor = _disableBackgroundColor; switch (_customType) { case GMButtonTypeGreenSemicircleBorder: case GMButtonTypeGreenRoundCornerBorder: case GMButtonTypeGraySemicircleBorder: case GMButtonTypeRedRoundCornerBorder: self.layer.borderColor = _disableBorderColor.CGColor; break; default: break; } } } #pragma mark - 支持自适应热区 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{ //默认不支持放大热区 if (!_enableAdaptive) { return [super pointInside:point withEvent:event]; } CGRect bounds = self.bounds; //若原热区小于 _adaptiveHotAreaWidth x _adaptiveHotAreaHeight,则放大热区,否则保持原大小不变 CGFloat widthDelta = MAX(_adaptiveHotAreaWidth - bounds.size.width, 0); CGFloat heightDelta = MAX(_adaptiveHotAreaHeight - bounds.size.height, 0); bounds = CGRectInset(bounds, -0.5 * widthDelta, -0.5 * heightDelta); return CGRectContainsPoint(bounds, point); } @end