1.背景
iOS7.0之后无法自定义UISwitch的图片,自定义一个UIView来实现开关功能,代替UISwitch。
2.实现
2.1 原理
新建一个UIView,在UIView中加入两个UIImageview。一个为背景图片,一个为滑块图片。
点击时实现动画,滑块滑动。使用的QQ录屏制作的GIF,请忽略黑圈。
2.2 代码
MySwitch.h
#import <UIKit/UIKit.h>
typedef void (^MyBlock) (BOOL OnStatus);
@protocol MySwitchDelegate
- (void)onStatusDelegate;
@end
@interface MySwitch : UIView
{
//背景View 滑块View
UIImageView *UIImageViewBack,*UIImageViewBlock;
//背景图片 滑块右图片 滑块左图片
UIImage *UIImageBack,*UIImageSliderRight,*UIImageSliderLeft;
}
//Switch 返回开关量block
@property (nonatomic,copy) MyBlock myBlock;
//Switch 返回开关量delegate
@property (nonatomic) id delegate;
//Switch 开关状态
@property (nonatomic) BOOL OnStatus;
//Switch 长 宽 滑块半径
@property (nonatomic) CGFloat Width,Height,CircleR;
//滑块距离边框边距
@property (nonatomic) CGFloat Gap;
/* 带有block 初始化
* @param frame
* @param gap 滑块距离边框的距离
* @param block
*
*/
- (id)initWithFrame:(CGRect)frame withGap:(CGFloat)gap statusChange:(MyBlock)block;
/* 初始化
* @param frame
* @param gap 滑块距离边框的距离
*
*/
- (id)initWithFrame:(CGRect)frame withGap:(CGFloat)gap;
//设置背景图片
-(void)setBackgroundImage:(UIImage *)image;
//设置左滑块图片
-(void)setLeftBlockImage:(UIImage *)image;
//设置右滑块图片
-(void)setRightBlockImage:(UIImage *)image;
@end
MySwitch.m
#import "MySwitch.h"
@implementation MySwitch
- (id)initWithFrame:(CGRect)frame withGap:(CGFloat)gap{
self = [super initWithFrame:frame];
if(self){
//默认选中On状态
_OnStatus=YES;
_Gap=gap;
_Width=frame.size.width;
_Height=frame.size.height;
_CircleR=(_Height-2*_Gap)/2;
self.backgroundColor=[UIColor whiteColor];
//设置背景
UIImageViewBack=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, _Width, _Height)];
UIImageViewBack.backgroundColor=[UIColor lightGrayColor];
[self addSubview:UIImageViewBack];
//设置 滑块图片
UIImageViewBlock=[[UIImageView alloc]initWithFrame:CGRectMake(_Width-_Height+_Gap, _Gap, 2*_CircleR, 2*_CircleR)];
UIImageViewBlock.backgroundColor=[UIColor whiteColor];
[self addSubview:UIImageViewBlock];
self.userInteractionEnabled=YES;
//创建手势对象
UITapGestureRecognizer *tap =[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];
tap.numberOfTapsRequired =1;
tap.numberOfTouchesRequired =1;
[self addGestureRecognizer:tap];
}
return self;
}
- (id)initWithFrame:(CGRect)frame withGap:(CGFloat)gap statusChange:(MyBlock)block{
self = [super initWithFrame:frame];
if(self){
_myBlock=block;
//默认选中On状态
_OnStatus=YES;
_Gap=gap;
_Width=frame.size.width;
_Height=frame.size.height;
_CircleR=(_Height-2*_Gap)/2;
self.backgroundColor=[UIColor whiteColor];
//设置背景
UIImageViewBack=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, _Width, _Height)];
UIImageViewBack.backgroundColor=[UIColor lightGrayColor];
[self addSubview:UIImageViewBack];
//设置 滑块图片
UIImageViewBlock=[[UIImageView alloc]initWithFrame:CGRectMake(_Width-_Height+_Gap, _Gap, 2*_CircleR, 2*_CircleR)];
UIImageViewBlock.backgroundColor=[UIColor whiteColor];
[self addSubview:UIImageViewBlock];
self.userInteractionEnabled=YES;
//创建手势对象
UITapGestureRecognizer *tap =[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];
tap.numberOfTapsRequired =1;
tap.numberOfTouchesRequired =1;
[self addGestureRecognizer:tap];
}
return self;
}
-(void)tapAction:(UITapGestureRecognizer *)tap
{
//图片切换
if(_OnStatus){
_OnStatus=NO;
//滑块关闭动画
CABasicAnimation * ani = [CABasicAnimation animationWithKeyPath:@"position"];
ani.toValue = [NSValue valueWithCGPoint:CGPointMake(_CircleR+_Gap, _CircleR+_Gap)];
ani.removedOnCompletion = NO;
ani.fillMode = kCAFillModeForwards;
ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[UIImageViewBlock.layer addAnimation:ani forKey:@"PostionToLeft"];
if(UIImageSliderLeft){
UIImageViewBlock.image=UIImageSliderLeft;
}else{
UIImageViewBlock.backgroundColor=[UIColor grayColor];
}
}else{
_OnStatus=YES;
//滑块打开动画
CABasicAnimation * ani = [CABasicAnimation animationWithKeyPath:@"position"];
ani.toValue = [NSValue valueWithCGPoint:CGPointMake(_Width-_CircleR-_Gap, _CircleR+_Gap)];
ani.removedOnCompletion = NO;
ani.fillMode = kCAFillModeForwards;
ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[UIImageViewBlock.layer addAnimation:ani forKey:@"PostionToRight"];
if(UIImageSliderRight){
UIImageViewBlock.image=UIImageSliderRight;
}else{
UIImageViewBlock.backgroundColor=[UIColor whiteColor];
}
}
if(_myBlock) _myBlock(_OnStatus);
[_delegate onStatusDelegate];
}
//设置背景图片
-(void)setBackgroundImage:(UIImage *)image{
UIImageViewBack.backgroundColor=[UIColor clearColor];
UIImageBack=image;
UIImageViewBack.image=image;
}
//设置左滑块图片
-(void)setLeftBlockImage:(UIImage *)image{
UIImageViewBlock.backgroundColor=[UIColor clearColor];
UIImageSliderLeft=image;
UIImageViewBlock.image=image;
}
//设置右滑块图片
-(void)setRightBlockImage:(UIImage *)image{
UIImageViewBlock.backgroundColor=[UIColor clearColor];
UIImageSliderRight=image;
UIImageViewBlock.image=image;
}
@end
2.3 使用
1.复制MySwitch.h 和 MySwitch.m 到项目中
2.引入 #import "MySwitch.h"
3.新建 MySwitch 加入View 中
4.设置背景图片,滑块关闭(向左滑动)图片,滑块打开(向右滑动)图片。也可以不设置,默认。
4.可以使用block 也可以使用 delegate
使用block回调
mySwitchBlock=[[MySwitch alloc] initWithFrame:CGRectMake(150, 350, 57, 31) withGap:3.0 statusChange:^(BOOL OnStatus) {
if(OnStatus){
NSLog(@"打开");
}else{
NSLog(@"关闭");
}
}];
//设置背景图片
[mySwitch setBackgroundImage:[UIImage imageNamed:@"back.png"]];
[mySwitch setLeftBlockImage:[UIImage imageNamed:@"left_slider.png"]];
[mySwitch setRightBlockImage:[UIImage imageNamed:@"right_slider.png"]];
使用delegate代理回调
//初始化mySwitch
mySwitch=[[MySwitch alloc] initWithFrame:CGRectMake(150, 250, 57, 31) withGap:2.0];
//设置背景图片
[mySwitch setBackgroundImage:[UIImage imageNamed:@"back.png"]];
[mySwitch setLeftBlockImage:[UIImage imageNamed:@"left_slider.png"]];
[mySwitch setRightBlockImage:[UIImage imageNamed:@"right_slider.png"]];
mySwitch.delegate=self;
- (void)onStatusDelegate{
if(mySwitch.OnStatus){
NSLog(@"打开");
}else{
NSLog(@"关闭");
}
}
3 最后
设置图片效果
设置图片.gif未设置图片效果
默认开关.gif注意:如果未设置图片,滑块与边框距离,滑块颜色,背景颜色都可在源代码中更改。
网友评论