看了好多自定义switch控件的demo 大多用UIview + label +imageView 实现的 还有用UIsilder实现的 感觉都不是特别满意
遂 自己写个一个 可以设置开关状态 BOOL isOn;
点击也可以触发valueChanged方法 简单粗暴
控件 继承与UIcontrol
OK 接下来上代码。。。
ZHSwitch的。h文件如下
#import <UIKit/UIKit.h>
@interface ZHSwitch : UIControl
{
// private member
BOOL m_touchedSelf;
BOOL on;
}
@property (nonatomic, assign, getter = isOn) BOOL on;
@property (nonatomic, strong) UIColor *onTintColor;
@property (nonatomic, strong) UIColor *tintColor;
@property (nonatomic, strong) UIColor *thumbTintColor;
@property (nonatomic, assign) NSInteger switchKnobSize;
@property (nonatomic, strong) UIColor *textColor;
@property (nonatomic, strong) UIFont *textFont;
@property (nonatomic, strong) NSString *onText;
@property (nonatomic, strong) NSString *offText;
@property (nonatomic, strong) UIView *onContentView;
/** 显示状态背景View */
@property (nonatomic,strong) UIImageView *onContentBgView;
@property (nonatomic, strong) UIView *offContentView;
/** 关闭状态背景View */
@property (nonatomic,strong) UIImageView *offContentBgView;
//款间距
@property (nonatomic, assign) NSInteger ballWithSize;
//竖着的间距
@property (nonatomic, assign) NSInteger ballHightSize;
@property (nonatomic,assign) NSInteger ballSize;
@property (nonatomic, strong) UIView *knobView;
/** 中间按钮背景View */
@property (nonatomic,strong) UIImageView *knobBgView;
- (void)setOn:(BOOL)on animated:(BOOL)animated;
- (id)initWithFrame:(CGRect)frame
onColor:(UIColor *)onColor
offColor:(UIColor *)offColor
font:(UIFont *)font
ballSize:(NSInteger )ballSize
onContentBgViewStr:(NSString *)onContentBgViewStr
offContentBgViewStr:(NSString *)offContentBgViewStr
knobBgViewStr:(NSString *)knobBgViewStr;
#import "ZHSwitch.h"
#define ZHSwitchMaxHeight 80.0f
#define ZHSwitchMinHeight 20.0f
#define ZHSwitchMinWidth 40.0f
@interface ZHSwitch ()
@property (nonatomic, strong) UIView *containerView;
@property (nonatomic, strong) UIColor *onColor;
@property (nonatomic, strong) UIFont * font;
@property (nonatomic, strong) UIColor *offColor;
@property (nonatomic, strong) UILabel *onLabel;
@property (nonatomic, strong) UILabel *offLabel;
/** 显示状态背景图名字 */
@property (nonatomic,copy)NSString *onContentBgViewStr;
/** 关闭状态背景图名字 */
@property (nonatomic,copy)NSString *offContentBgViewStr;
/** 中间状态背景图名字 */
@property (nonatomic,copy)NSString *knobBgViewStr;
- (void)commonInit;
- (CGRect)roundRect:(CGRect)frameOrBounds;
@end
@implementation ZHSwitch
- (id)initWithFrame:(CGRect)frame
onColor:(UIColor *)onColor
offColor:(UIColor *)offColor
font:(UIFont *)font
ballSize:(NSInteger )ballSize
onContentBgViewStr:(NSString *)onContentBgViewStr
offContentBgViewStr:(NSString *)offContentBgViewStr
knobBgViewStr:(NSString *)knobBgViewStr
{
self = [super initWithFrame:[self roundRect:frame]];
if (self) {
self.ballSize = ballSize;
self.font = font;
self.onColor = onColor;
self.offColor = offColor;
self.onContentBgViewStr = onContentBgViewStr;
self.offContentBgViewStr = offContentBgViewStr;
self.knobBgViewStr = knobBgViewStr;
[self commonInit];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
[self commonInit];
}
return self;
}
- (void)setBounds:(CGRect)bounds
{
[super setBounds:[self roundRect:bounds]];
[self setNeedsLayout];
}
- (void)setFrame:(CGRect)frame
{
[super setFrame:[self roundRect:frame]];
[self setNeedsLayout];
}
- (void)setOnText:(NSString *)onText
{
if (_onText != onText) {
_onText = onText;
_onLabel.text = onText;
}
}
- (void)setOffText:(NSString *)offText
{
if (_offText != offText) {
_offText = offText;
_offLabel.text = offText;
}
}
- (void)setOnTintColor:(UIColor *)onTintColor
{
if (_onTintColor != onTintColor) {
_onTintColor = onTintColor;
_onContentView.backgroundColor = onTintColor;
}
}
- (void)setTintColor:(UIColor *)tintColor
{
if (_tintColor != tintColor) {
_tintColor = tintColor;
_offContentView.backgroundColor = tintColor;
}
}
- (void)setThumbTintColor:(UIColor *)thumbTintColor
{
if (_thumbTintColor != thumbTintColor) {
_thumbTintColor = thumbTintColor;
_knobView.backgroundColor = _thumbTintColor;
}
}
- (void)layoutSubviews
{
[super layoutSubviews];
self.containerView.frame = self.bounds;
CGFloat r = CGRectGetHeight(self.containerView.bounds) / 2.0;
self.containerView.layer.cornerRadius = r;
self.containerView.layer.masksToBounds = YES;
CGFloat margin = (CGRectGetHeight(self.bounds) - self.ballSize) / 2.0;
if (!on) {
// frame of off status
self.onContentView.frame = CGRectMake(-1 * CGRectGetWidth(self.containerView.bounds),
0,
CGRectGetWidth(self.containerView.bounds),
CGRectGetHeight(self.containerView.bounds));
self.offContentView.frame = CGRectMake(0,
0,
CGRectGetWidth(self.containerView.bounds),
CGRectGetHeight(self.containerView.bounds));
self.knobView.frame = CGRectMake(margin,
margin,
self.ballSize,
self.ballSize);
} else {
// frame of on status
self.onContentView.frame = CGRectMake(0,
0,
CGRectGetWidth(self.containerView.bounds),
CGRectGetHeight(self.containerView.bounds));
self.offContentView.frame = CGRectMake(0,
CGRectGetWidth(self.containerView.bounds),
CGRectGetWidth(self.containerView.bounds),
CGRectGetHeight(self.containerView.bounds));
self.knobView.frame = CGRectMake(CGRectGetWidth(self.containerView.bounds) - margin - self.ballSize,
margin,
self.ballSize,
self.ballSize);
}
CGFloat lHeight = 20.0f;
CGFloat lMargin = r - (sqrtf(powf(r, 2) - powf(lHeight / 2.0, 2))) + margin;
self.onLabel.frame = CGRectMake(lMargin,
r - lHeight / 2.0,
CGRectGetWidth(self.onContentView.bounds) - lMargin - self.ballSize - 2 * margin,
lHeight);
self.offLabel.frame = CGRectMake(self.ballSize + 2 * margin,
r - lHeight / 2.0,
CGRectGetWidth(self.onContentView.bounds) - lMargin - self.ballSize - 2 * margin,
lHeight);
_on = on;
}
- (void)setOn:(BOOL)turnOn
{
[self setOn:turnOn animated:NO];
}
- (void)setOn:(BOOL)turnOn animated:(BOOL)animated{
on = turnOn;
CGFloat margin = (CGRectGetHeight(self.bounds) - self.ballSize) / 2.0;
if (!animated) {
if (!on) {
// frame of off status
self.onContentView.frame = CGRectMake(-1 * CGRectGetWidth(self.containerView.bounds),
0,
CGRectGetWidth(self.containerView.bounds),
CGRectGetHeight(self.containerView.bounds));
self.offContentView.frame = CGRectMake(0,
0,
CGRectGetWidth(self.containerView.bounds),
CGRectGetHeight(self.containerView.bounds));
self.knobView.frame = CGRectMake(margin,
margin,
self.ballSize,
self.ballSize);
} else {
// frame of on status
self.onContentView.frame = CGRectMake(0,
0,
CGRectGetWidth(self.containerView.bounds),
CGRectGetHeight(self.containerView.bounds));
self.offContentView.frame = CGRectMake(0,
CGRectGetWidth(self.containerView.bounds),
CGRectGetWidth(self.containerView.bounds),
CGRectGetHeight(self.containerView.bounds));
self.knobView.frame = CGRectMake(CGRectGetWidth(self.containerView.bounds) - margin - self.ballSize,
margin,
self.ballSize,
self.ballSize);
}
} else {
if (on) {
[UIView animateWithDuration:0.25
animations:^{
self.knobView.frame = CGRectMake(CGRectGetWidth(self.containerView.bounds) - margin - self.ballSize,
margin,
self.ballSize,
self.ballSize);
}
completion:^(BOOL finished){
self.onContentView.frame = CGRectMake(0,
0,
CGRectGetWidth(self.containerView.bounds),
CGRectGetHeight(self.containerView.bounds));
self.offContentView.frame = CGRectMake(0,
CGRectGetWidth(self.containerView.bounds),
CGRectGetWidth(self.containerView.bounds),
CGRectGetHeight(self.containerView.bounds));
}];
} else {
[UIView animateWithDuration:0.25
animations:^{
self.knobView.frame = CGRectMake(margin,
margin,
self.ballSize,
self.ballSize);
}
completion:^(BOOL finished){
self.onContentView.frame = CGRectMake(-1 * CGRectGetWidth(self.containerView.bounds),
0,
CGRectGetWidth(self.containerView.bounds),
CGRectGetHeight(self.containerView.bounds));
self.offContentView.frame = CGRectMake(0,
0,
CGRectGetWidth(self.containerView.bounds),
CGRectGetHeight(self.containerView.bounds));
}];
}
}
_on = on;
}
#pragma mark - Private API
- (void)commonInit
{
self.backgroundColor = [UIColor clearColor];
_onTintColor = self.onColor;
_tintColor = self.offColor;
if ([_knobBgViewStr isEqualToString:@""] || _knobBgViewStr == nil) {
_thumbTintColor = [UIColor colorWithWhite:1 alpha:1];
} else{
_thumbTintColor = [UIColor clearColor];
}
_textFont = self.font;
_textColor = [UIColor whiteColor];
_containerView = [[UIView alloc] initWithFrame:self.bounds];
_containerView.backgroundColor = [UIColor clearColor];
[self addSubview:_containerView];
_onContentView = [[UIView alloc] initWithFrame:self.bounds];
_onContentView.backgroundColor = _onTintColor;
[_containerView addSubview:_onContentView];
_onContentBgView =[[UIImageView alloc]init];
_onContentBgView.image =[UIImage imageNamed:self.onContentBgViewStr];
_onContentBgView.frame = _onContentView.bounds;
_onContentBgView.contentMode = UIViewContentModeScaleAspectFit;
[_onContentView addSubview:_onContentBgView];
_offContentView = [[UIView alloc] initWithFrame:self.bounds];
_offContentView.backgroundColor = _tintColor;
[_containerView addSubview:_offContentView];
_offContentBgView =[[UIImageView alloc]init];
_offContentBgView.image =[UIImage imageNamed:self.offContentBgViewStr];
_offContentBgView.frame = _offContentView.bounds;
_offContentBgView.contentMode = UIViewContentModeScaleAspectFit;
[_offContentView addSubview:_offContentBgView];
_knobView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.ballSize, self.ballSize)];
_knobView.backgroundColor = _thumbTintColor;
_knobView.layer.cornerRadius = self.ballSize / 2.0;
[_containerView addSubview:_knobView];
_knobBgView =[[UIImageView alloc]init];
_knobBgView.image =[UIImage imageNamed:self.knobBgViewStr];
_knobBgView.frame = _knobView.bounds;
_knobBgView.contentMode = UIViewContentModeScaleAspectFit;
[_knobView addSubview:_knobBgView];
_onLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_onLabel.backgroundColor = [UIColor clearColor];
_onLabel.textAlignment = NSTextAlignmentCenter;
_onLabel.textColor = _textColor;
_onLabel.font = _font;
_onLabel.text = _onText;
[_onContentView addSubview:_onLabel];
_offLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_offLabel.backgroundColor = [UIColor clearColor];
_offLabel.textAlignment = NSTextAlignmentCenter;
_offLabel.textColor = _textColor;
_offLabel.font = _font;
_offLabel.text = _offText;
[_offContentView addSubview:_offLabel];
}
- (CGRect)roundRect:(CGRect)frameOrBounds
{
CGRect newRect = frameOrBounds;
if (newRect.size.height > ZHSwitchMaxHeight) {
newRect.size.height = ZHSwitchMaxHeight;
}
if (newRect.size.height < ZHSwitchMinHeight) {
newRect.size.height = ZHSwitchMinHeight;
}
if (newRect.size.width < ZHSwitchMinWidth) {
newRect.size.width = ZHSwitchMinWidth;
}
return newRect;
}
- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
[super endTrackingWithTouch:touch withEvent:event];
m_touchedSelf = YES;
[self setOn:on animated:YES];
}
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
[super touchesBegan:touches withEvent:event];
m_touchedSelf = NO;
on = !on;
}
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
[super touchesEnded:touches withEvent:event];
if (!m_touchedSelf)
{
[self setOn:on animated:YES];
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
}
@end