iOS开发-UISwitch自定义图片

作者: 3a6b730f91a6 | 来源:发表于2017-06-06 14:42 被阅读589次

    1.背景

    iOS7.0之后无法自定义UISwitch的图片,自定义一个UIView来实现开关功能,代替UISwitch。

    2.实现

    2.1 原理

    新建一个UIView,在UIView中加入两个UIImageview。一个为背景图片,一个为滑块图片。
    点击时实现动画,滑块滑动。使用的QQ录屏制作的GIF,请忽略黑圈。

    mySwitch.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

    注意:如果未设置图片,滑块与边框距离,滑块颜色,背景颜色都可在源代码中更改。

    相关文章

      网友评论

        本文标题:iOS开发-UISwitch自定义图片

        本文链接:https://www.haomeiwen.com/subject/iaigfxtx.html