网上搜了一下,基本都是讲的如何自定义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 <UIKit/UIKit.h>
@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
下面是效果图
最后:如果需求变化,又要使用系统的样式:屏蔽掉两句话即可