1、CHSwitch.h

//
// 文 件 名:CHSwitch.h
//
// 版权所有:Copyright © 2018 lelight. All rights reserved.
// 创 建 者:lelight
// 创建日期:2018/12/19.
// 文档说明:
// 修 改 人:
// 修改日期:
// #import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN typedef enum {
CHSwitchShapeOval,
CHSwitchShapeRectangle,
CHSwitchShapeRectangleNoCorner
} CHSwitchShape; @interface CHSwitch : UIControl <UIGestureRecognizerDelegate> /** 开关状态读取与设置 */
@property (nonatomic, getter = isOn) BOOL on;
/** 开关形状枚举值:默认CHSwitchShapeOval */
@property (nonatomic, assign) CHSwitchShape shape;
/** 打开时的颜色 */
@property (nonatomic, strong) UIColor *onTintColor;
/** 关闭时的颜色 */
@property (nonatomic, strong) UIColor *tintColor;
/** 圆点颜色 */
@property (nonatomic, strong) UIColor *thumbTintColor;
/** 是否需要阴影效果 */
@property (nonatomic, assign) BOOL shadow;
/** 关闭时的阴影颜色 */
@property (nonatomic, strong) UIColor *tintBorderColor;
/** 打开时的阴影颜色 */
@property (nonatomic, strong) UIColor *onTintBorderColor; @end NS_ASSUME_NONNULL_END

2、CHSwitch.m

//
// 文 件 名:CHSwitch.m
//
// 版权所有:Copyright © 2018 lelight. All rights reserved.
// 创 建 者:lelight
// 创建日期:2018/12/19.
// 文档说明:
// 修 改 人:
// 修改日期:
// #import "CHSwitch.h"
#import <QuartzCore/QuartzCore.h> static const CGFloat kAnimateDuration = 0.3f;
static const CGFloat kHorizontalAdjustment = 3.0f;
static const CGFloat kRectShapeCornerRadius = 4.0f;
static const CGFloat kThumbShadowOpacity = 0.3f;
static const CGFloat kThumbShadowRadius = 0.5f;
static const CGFloat kSwitchBorderWidth = 1.75f; @interface CHSwitch () @property (nonatomic, strong) UIView *onBackgroundView;
@property (nonatomic, strong) UIView *offBackgroundView;
@property (nonatomic, strong) UIView *thumbView; @end @implementation CHSwitch @synthesize onBackgroundView = _onBackgroundView;
@synthesize offBackgroundView = _offBackgroundView;
@synthesize thumbView = _thumbView;
@synthesize on = _on;
@synthesize shape = _shape;
@synthesize onTintColor = _onTintColor;
@synthesize tintColor = _tintColor;
@synthesize thumbTintColor = _thumbTintColor;
@synthesize shadow = _shadow;
@synthesize onTintBorderColor = _onTintBorderColor;
@synthesize tintBorderColor = _tintBorderColor; #pragma mark - View
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setupUI];
}
return self;
} - (void) awakeFromNib {
[super awakeFromNib]; [self setupUI];
} - (void)setupUI {
self.shape = CHSwitchShapeOval; [self setBackgroundColor:[UIColor clearColor]]; // Background view for ON
self.onBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
[self.onBackgroundView setBackgroundColor:[UIColor colorWithRed:(19.0f/255.0f) green:(121.0f/255.0f) blue:(208.0f/255.0f) alpha:1.0f]];
[self.onBackgroundView.layer setCornerRadius:self.frame.size.height/2];
[self.onBackgroundView.layer setShouldRasterize:YES];
[self.onBackgroundView.layer setRasterizationScale:[UIScreen mainScreen].scale];
[self addSubview:self.onBackgroundView]; // Background view for OFF
self.offBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
[self.offBackgroundView setBackgroundColor:[UIColor whiteColor]];
[self.offBackgroundView.layer setCornerRadius:self.frame.size.height/2];
[self.offBackgroundView.layer setShouldRasterize:YES];
[self.offBackgroundView.layer setRasterizationScale:[UIScreen mainScreen].scale];
[self addSubview:self.offBackgroundView]; // Round switch view
self.thumbView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.height-kHorizontalAdjustment, self.frame.size.height-kHorizontalAdjustment)];
[self.thumbView setBackgroundColor:[UIColor whiteColor]];
[self.thumbView setUserInteractionEnabled:YES];
[self.thumbView.layer setCornerRadius:(self.frame.size.height-kHorizontalAdjustment)/2];
[self.thumbView.layer setShadowOffset:CGSizeMake(0, 1)];
[self.thumbView.layer setShouldRasterize:YES];
[self.thumbView.layer setShadowOpacity:kThumbShadowOpacity];
[self.thumbView.layer setRasterizationScale:[UIScreen mainScreen].scale];
[self addSubview:self.thumbView];
self.shadow = YES; // Default to OFF position
[self.thumbView setCenter:CGPointMake(self.thumbView.frame.size.width/2, self.frame.size.height/2)]; // Handle Thumb Tap Gesture
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(handleSwitchTap:)];
[tapGestureRecognizer setDelegate:self];
[self.thumbView addGestureRecognizer:tapGestureRecognizer]; // Handle Background Tap Gesture
UITapGestureRecognizer *tapBgGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleBgTap:)];
[tapBgGestureRecognizer setDelegate:self];
[self addGestureRecognizer:tapBgGestureRecognizer]; // Handle Thumb Pan Gesture
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[panGestureRecognizer setDelegate:self];
[self.thumbView addGestureRecognizer:panGestureRecognizer]; [self setOn:NO];
} #pragma mark - Accessor
- (BOOL)isOn {
return _on;
} - (void)setOn:(BOOL)on {
if (_on != on)
_on = on; if (_on) {
[self.onBackgroundView setAlpha:1.0];
self.offBackgroundView.transform = CGAffineTransformMakeScale(0.0, 0.0); self.thumbView.center = CGPointMake(self.onBackgroundView.frame.size.width - (self.thumbView.frame.size.width + kHorizontalAdjustment)/2, self.thumbView.center.y);
}
else {
[self.onBackgroundView setAlpha:0.0];
self.offBackgroundView.transform = CGAffineTransformMakeScale(1.0, 1.0); self.thumbView.center = CGPointMake((self.thumbView.frame.size.width+kHorizontalAdjustment)/2, self.thumbView.center.y);
}
} - (void)setOnTintColor:(UIColor *)color
{
if (_onTintColor != color)
_onTintColor = color; [self.onBackgroundView setBackgroundColor:color];
} - (void)setOnTintBorderColor:(UIColor *)color
{
if (_onTintBorderColor != color)
_onTintBorderColor = color; [self.onBackgroundView.layer setBorderColor:color.CGColor]; if (color)
[self.onBackgroundView.layer setBorderWidth:kSwitchBorderWidth];
else
[self.onBackgroundView.layer setBorderWidth:0.0];
} - (void)setTintColor:(UIColor *)color
{
if (_tintColor != color)
_tintColor = color; [self.offBackgroundView setBackgroundColor:color];
} - (void)setTintBorderColor:(UIColor *)color
{
if (_tintBorderColor != color)
_tintBorderColor = color; [self.offBackgroundView.layer setBorderColor:color.CGColor]; if (color)
[self.offBackgroundView.layer setBorderWidth:kSwitchBorderWidth];
else
[self.offBackgroundView.layer setBorderWidth:0.0];
} - (void)setThumbTintColor:(UIColor *)color
{
if (_thumbTintColor != color)
_thumbTintColor = color; [self.thumbView setBackgroundColor:color];
} - (void)setShape:(CHSwitchShape)newShape
{
if (_shape != newShape)
_shape = newShape; if (newShape == CHSwitchShapeOval)
{
[self.onBackgroundView.layer setCornerRadius:self.frame.size.height/2];
[self.offBackgroundView.layer setCornerRadius:self.frame.size.height/2];
[self.thumbView.layer setCornerRadius:(self.frame.size.height-kHorizontalAdjustment)/2];
}
else if (newShape == CHSwitchShapeRectangle)
{
[self.onBackgroundView.layer setCornerRadius:kRectShapeCornerRadius];
[self.offBackgroundView.layer setCornerRadius:kRectShapeCornerRadius];
[self.thumbView.layer setCornerRadius:kRectShapeCornerRadius];
}
else if (newShape == CHSwitchShapeRectangleNoCorner)
{
[self.onBackgroundView.layer setCornerRadius:0];
[self.offBackgroundView.layer setCornerRadius:0];
[self.thumbView.layer setCornerRadius:0];
}
} - (void)setShadow:(BOOL)showShadow
{
if (_shadow != showShadow)
_shadow = showShadow; if (showShadow)
{
[self.thumbView.layer setShadowOffset:CGSizeMake(0, 1)];
[self.thumbView.layer setShadowRadius:kThumbShadowRadius];
[self.thumbView.layer setShadowOpacity:kThumbShadowOpacity];
}
else
{
[self.thumbView.layer setShadowRadius:0.0];
[self.thumbView.layer setShadowOpacity:0.0];
}
} #pragma mark - Animation
- (void)animateToDestination:(CGPoint)centerPoint withDuration:(CGFloat)duration switch:(BOOL)on
{
[UIView animateWithDuration:duration
delay:0.0f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.thumbView.center = centerPoint; if (on)
{
[self.onBackgroundView setAlpha:1.0];
}
else
{
[self.onBackgroundView setAlpha:0.0];
} }
completion:^(BOOL finished) {
if (finished)
{
[self updateSwitch:on];
} }]; [UIView animateWithDuration:duration
delay:0.075f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
if (on)
{
self.offBackgroundView.transform = CGAffineTransformMakeScale(0.0, 0.0);
}
else
{
self.offBackgroundView.transform = CGAffineTransformMakeScale(1.0, 1.0);
} }
completion:^(BOOL finished) {
}];
} #pragma mark - Gesture Recognizers
- (void)handlePan:(UIPanGestureRecognizer *)recognizer
{
CGPoint translation = [recognizer translationInView:self.thumbView]; // Check the new center to see if within the boud
CGPoint newCenter = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y);
if (newCenter.x < (recognizer.view.frame.size.width+kHorizontalAdjustment)/2 || newCenter.x > self.onBackgroundView.frame.size.width-(recognizer.view.frame.size.width+kHorizontalAdjustment)/2)
{
// New center is Out of bound. Animate to left or right position
if(recognizer.state == UIGestureRecognizerStateBegan ||
recognizer.state == UIGestureRecognizerStateChanged)
{
CGPoint velocity = [recognizer velocityInView:self.thumbView]; if (velocity.x >= 0)
{
// Animate move to right
[self animateToDestination:CGPointMake(self.onBackgroundView.frame.size.width - (self.thumbView.frame.size.width+kHorizontalAdjustment)/2, recognizer.view.center.y) withDuration:kAnimateDuration switch:YES];
}
else
{
// Animate move to left
[self animateToDestination:CGPointMake((self.thumbView.frame.size.width+kHorizontalAdjustment)/2, recognizer.view.center.y) withDuration:kAnimateDuration switch:NO];
} } return;
} // Only allow vertical pan
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.thumbView]; CGPoint velocity = [recognizer velocityInView:self.thumbView]; if(recognizer.state == UIGestureRecognizerStateEnded)
{
if (velocity.x >= 0)
{
if (recognizer.view.center.x < self.onBackgroundView.frame.size.width - (self.thumbView.frame.size.width+kHorizontalAdjustment)/2)
{
// Animate move to right
[self animateToDestination:CGPointMake(self.onBackgroundView.frame.size.width - (self.thumbView.frame.size.width+kHorizontalAdjustment)/2, recognizer.view.center.y) withDuration:kAnimateDuration switch:YES];
}
}
else
{
// Animate move to left
[self animateToDestination:CGPointMake((self.thumbView.frame.size.width+kHorizontalAdjustment)/2, recognizer.view.center.y) withDuration:kAnimateDuration switch:NO];
}
}
} - (void)handleSwitchTap:(UIPanGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateEnded)
{
if (self.isOn)
{
// Animate move to left
[self animateToDestination:CGPointMake((self.thumbView.frame.size.width+kHorizontalAdjustment)/2, recognizer.view.center.y) withDuration:kAnimateDuration switch:NO];
}
else
{
// Animate move to right
[self animateToDestination:CGPointMake(self.onBackgroundView.frame.size.width - (self.thumbView.frame.size.width+kHorizontalAdjustment)/2, recognizer.view.center.y) withDuration:kAnimateDuration switch:YES];
}
}
} - (void)handleBgTap:(UIPanGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateEnded)
{
if (self.isOn)
{
// Animate move to left
[self animateToDestination:CGPointMake((self.thumbView.frame.size.width+kHorizontalAdjustment)/2, self.thumbView.center.y) withDuration:kAnimateDuration switch:NO];
}
else
{
// Animate move to right
[self animateToDestination:CGPointMake(self.onBackgroundView.frame.size.width - (self.thumbView.frame.size.width+kHorizontalAdjustment)/2, self.thumbView.center.y) withDuration:kAnimateDuration switch:YES];
}
}
} #pragma mark -
- (void)updateSwitch:(BOOL)on
{
if (_on != on)
_on = on; [self sendActionsForControlEvents:UIControlEventValueChanged];
} @end

可变大小、颜色边框、样式的UISwitch的更多相关文章

  1. Android CheckBox修改大小、边框颜色,以及自定义CheckBox;

    CheckBox修改大小: android:scaleX="0.8" android:scaleY="0.8" CheckBox修改边框颜色,注意不是背景色: ...

  2. css盒子模型之边框宽度,边框颜色与边框样式

    /* width和height只是设置盒子内容区的大小,而不是盒子的整个大小, 盒子可见框的大小由内容区,内边距和边框共同决定. */ .box1 { /* 设置内容区的宽度为400px */ wid ...

  3. css中的边框样式

    在盒子模型中,盒子的边框是其重要的样式,通过边框我们可以很方便地看出盒子的长宽以及大小.边框的特性可以通过边框线,边框的宽度及颜色来呈现. 1,边框线 边框线指的是边框线条的样式,包括实线,虚线,点划 ...

  4. css边框样式、边框配色、边框阴影、边框圆角、图片边框

     边框样式 点线式边框 破折线式边框 直线式边框 双线式边框 槽线式边框 脊线式边框 内嵌效果的边框 突起效果的边框 <div style="width: 300px; height: ...

  5. [转]CSS如何设置html table表格边框样式

    原文地址:http://www.divcss5.com/wenji/w503.shtml 对table设置css样式边框,分为几种情况: 1.只对table设置边框 2.对td设置边框 3.对tabl ...

  6. UWP VirtualizedVariableSizedGridView 支持可虚拟化可变大小Item的View(二)

    上篇UWP VirtualizedVariableSizedGridView 支持可虚拟化可变大小Item的View(一) 讲到该控件的需要和设计过程. 这篇讲讲开发过程中一些重要问题解决. 1.支持 ...

  7. CSS3初学篇章_4(边框样式/段落样式)

    边框样式 1.边框线语法:border-style : none | hidden | dotted | dashed | solid | double | groove | ridge | inse ...

  8. 改变 Panel 跟 groupbox边框样式

    更改panel和groupbox的边框颜色因为在控件的属性中没有设置边框颜色的属性只有一个设置边框样式,遂在网络中搜寻出一下方法: panel的边框颜色在paint中重新对颜色进行定义 private ...

  9. CSS 边框样式

    CSS 边框样式 直线边框样式 <html> <body> <!-- border: 1px 边框像素为1.solid red 边框样式以及边框颜色 --> < ...

  10. python 输出颜色与样式的方法

    上次遇到这个问题就想写下来,其实当时我也不怎么会,老师说这个东西不需要理解,只需要死记硬背,写的多了就记住了,所以今天搜集了几篇文章,加上自己的理解,写下了这篇python 输出颜色的样式与方法的文章 ...

随机推荐

  1. Oracle redo与undo

    Undo and redo Oracle最重要的两部分数据,undo 与redo,redo(重做信息)是oracle在线(或归档)重做日志文件中记录的信息,可以利用redo重放事务信息,undo(撤销 ...

  2. JSON数据的解析方法

    1.JSON.parse(json) 2.new Function(“return ” + json) (); 3.eval(“(”+json+”)”)

  3. 第二章 Java内存区域与内存溢出异常(待续)

    ·········

  4. python--numpy学习(一)

    NumPy 部分功能如下: ndarray,一个具有矢量运算符和复杂广播能力的快速节省空间的多维数组 用于对数组数据进行快速运算的标准数学函数 用于读写磁盘数据的工具以及用于操作内存映射文件的工具 线 ...

  5. Python图片转字符画

    PIL安装很麻烦,推荐下载exe直接安装 PIL官网:http://pythonware.com/products/pil/ 但现在里面下载链接访问不了,我把32位和64位版本上传到博客园以供下载 P ...

  6. 前端自动化之npm

    npm——node依赖包管理工具 安装: 1.在nvm目录下复制npm和npm-cath文件夹 2.配置环境变量. 使用: 1.在项目文件夹,shift+右键打开命令窗口 2.npm init     ...

  7. @Value关于static字段的注入

    @Component public class BaseCode { //应用key public static String APP_KEY; //应用密钥 public static String ...

  8. git rm简介

    本文翻译整理自:http://web.mit.edu/~mkgray/project/silk/root/afs/sipb/project/git/git-doc/git-rm.html 在git中我 ...

  9. 电商模式O2O、C2C、B2B、B2C

    电商模式O2O.C2C.B2B.B2C o2o o2o 是 online to offline 分为四种运营模式 1.online to offline 是线上交易到线下消费体验 2.offline ...

  10. PHP数据结构之二 线性表中的顺序表的PHP实现

    线性表 (一)基本特点:最基本.最简单.最常用的一种数据结构 在这种结构中: 1.存在一个唯一的被称为“第一个”的数据元素: 2.存在一个唯一的被称为“最后一个”的数据元素: 3.除第一个元素外,每个 ...