本文为CocoaChina网友_小呵呵投稿
网上搜了一下,基本都是讲的如何自定义UISwitch控件。我今天来写一篇如何不更改(或最少的更改)原有工程里各个类关于UISwitch的声明、设置、调用代码,平滑的将系统UISwitch样式大小更改为客户需要求展示的样式。
看一下系统的UISwitch的展示效果
系统的UISwitch的提供的属性和方法:
方法很少,能让开发者修改的地方也很少:
1.frame是修改不了的
2.通过动画的方式可以放大缩小实现改变大小的效果,但是里面圆圈和外部的比例还是变不了
3.圆圈的颜色无法改变
为了将工程中所有用到这个控件的地方都改变其展示样式,
1.需要自定义一个控件,采用 UIImageView + UIButton的方式,UIImageView展示的是类似椭圆形图片,UIButton是上面的圆圈。通过点击button用动画来移动位置并更改背景图。
2.需要实现的方法和声明的属性(和系统的基本一致)
@property(nullable, nonatomic, strong) UIColor *onTintColor;
//@property(nullable, nonatomic, strong) UIColor *thumbTintColor;
@property(nonatomic,getter=isOn) BOOL on;
- (instancetype)init;
- (void)setOn:(BOOL)on animated:(BOOL)animated;
3.在pch文件 加上
#import "PublicSwitchView.h"
#define UISwitch PublicSwitchView
4.实现原理:通过写和系统一样的方法名来达到只更改类名的效果,通过宏定义一次更换所有地方的类名。
具体代码
// // PublicSwitchView.h // Demo // // Created by yfc on 2017/10/14. // Copyright ? 2017年 yfc. All rights reserved. // #import @interface PublicSwitchView : UIControl{ UIImageView *imageview; UIButton *btn; } @property(nullable, nonatomic, strong) UIColor *onTintColor; //@property(nullable, nonatomic, strong) UIColor *thumbTintColor; @property(nonatomic,getter=isOn) BOOL on; - (void)setOn:(BOOL)on animated:(BOOL)animated; @end
// // PublicSwitchView.m // Demo // // Created by yfc on 2017/10/14. // Copyright ? 2017年 yfc. All rights reserved. // #import "PublicSwitchView.h" #import "UIView+Utils.h" @implementation PublicSwitchView - (instancetype)init{ CGRect frame = CGRectMake(0, 0, 50, 25); if (self = [super initWithFrame:frame]) { self.backgroundColor = [UIColor clearColor]; // //椭圆背景 // imageview = [[UIImageView alloc]initWithFrame:frame]; imageview.image = [UIImage imageNamed:@"graySwitch"]; [self addSubview:imageview]; // //圆圈 // double height = frame.size.height - 7; btn = [[UIButton alloc]initWithFrame:CGRectMake(5, 0, height, height)]; btn.layer.cornerRadius = btn.width / 2.0; btn.backgroundColor = [UIColor whiteColor]; [btn addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside]; btn.centerY = frame.size.height / 2.0; btn.userInteractionEnabled = YES; [self addSubview:btn]; [self addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside]; self.userInteractionEnabled = YES; } return self; } // //大小固定 // - (void)setFrame:(CGRect)frame{ CGRect frame_ = CGRectMake(frame.origin.x, frame.origin.y, 50, 25); [super setFrame:frame_]; } // //点击事件 // - (void)btnClicked:(UIButton *)btneee{ [UIView animateWithDuration:0.25 animations:^{ if (btn.left < 6) { btn.right = self.frame.size.width - 5; self.on = YES; imageview.image = [UIImage imageNamed:@"purpleSwitch"]; // //发送点击事件 // [self sendActionsForControlEvents:UIControlEventValueChanged]; }else{ btn.left = 5; imageview.image = [UIImage imageNamed:@"graySwitch"]; self.on = NO; // //发送点击事件 // [self sendActionsForControlEvents:UIControlEventValueChanged]; } }]; } // //带有动画的设置开关状态 // - (void)setOn:(BOOL)on{ _on = on; [UIView animateWithDuration:0.25 animations:^{ if (on == YES) { btn.right = self.frame.size.width - 5; imageview.image = [UIImage imageNamed:@"purpleSwitch"]; }else{ btn.left = 5; imageview.image = [UIImage imageNamed:@"graySwitch"]; } }]; } // //设置不可点击 // - (void)setEnabled:(BOOL)enabled{ [super setEnabled:enabled]; if (enabled == NO) { [self setOn:NO animated:NO]; imageview.image = [UIImage imageNamed:@"enabledSwitch"]; btn.backgroundColor = [UIColor colorWithRed:254/255.0 green:255/255.0 blue:255/255.0 alpha:1]; } } // //是否带有动画的设置开关状态 // - (void)setOn:(BOOL)on animated:(BOOL)animated;{ if (animated == YES) { self.on = on; }else{ _on = on; if (on == YES) { btn.right = self.frame.size.width - 5; imageview.image = [UIImage imageNamed:@"purpleSwitch"]; }else{ btn.left = 5; imageview.image = [UIImage imageNamed:@"graySwitch"]; } } } - (void)dealloc{ } @end
下面是效果图
最后:如果需求变化,又要使用系统的样式:屏蔽掉两句话即可