iOS自定义的UISwitch按钮

Wesley13
• 阅读 540

因为项目需要在UISwitch按钮上写文字,系统自带的UISwitch是这样的:

iOS自定义的UISwitch按钮

既不能写字,也不能改颜色,于是在网上找到了这么一个自定义的Switch按钮,具体出处找不见了。记录一下,怕以后找不见了。

先看下效果图:

iOS自定义的UISwitch按钮

按钮的样式很多,可以文字,可以写多行,文字大小和颜色都可以设置。

看下它的源码:

#import <Foundation/Foundation.h>


@interface HMCustomSwitch : UISlider {
    BOOL on;
    UIColor *tintColor;
    UIView *clippingView;
    UILabel *rightLabel;
    UILabel *leftLabel;
    
    // private member
    BOOL m_touchedSelf;
}

@property(nonatomic,getter=isOn) BOOL on;
@property (nonatomic,retain) UIColor *tintColor;
@property (nonatomic,retain) UIView *clippingView;
@property (nonatomic,retain) UILabel *rightLabel;
@property (nonatomic,retain) UILabel *leftLabel;

+ (HMCustomSwitch *) switchWithLeftText: (NSString *) tag1 andRight: (NSString *) tag2;

- (void)setOn:(BOOL)on animated:(BOOL)animated;

.m文件

#import "HMCustomSwitch.h"


@implementation HMCustomSwitch

@synthesize on;
@synthesize tintColor, clippingView, leftLabel, rightLabel;

+(HMCustomSwitch *)switchWithLeftText:(NSString *)leftText andRight:(NSString *)rightText
{
    HMCustomSwitch *switchView = [[HMCustomSwitch alloc] initWithFrame:CGRectZero];
    
    switchView.leftLabel.text = leftText;
    switchView.rightLabel.text = rightText;
    
    return [switchView autorelease];
}

-(id)initWithFrame:(CGRect)rect
{
    if ((self=[super initWithFrame:CGRectMake(rect.origin.x,rect.origin.y,95,27)]))
    {
        //        self.clipsToBounds = YES;
        
        [self awakeFromNib];        // do all setup in awakeFromNib so that control can be created manually or in a nib file
    }
    return self;
}

-(void)awakeFromNib
{
    [super awakeFromNib];
    
    self.backgroundColor = [UIColor clearColor];

    [self setThumbImage:[UIImage imageNamed:@"switchThumb.png"] forState:UIControlStateNormal];
    [self setMinimumTrackImage:[UIImage imageNamed:@"switchBlueBg.png"] forState:UIControlStateNormal];
    [self setMaximumTrackImage:[UIImage imageNamed:@"switchOffPlain.png"] forState:UIControlStateNormal];
    
    self.minimumValue = 0;
    self.maximumValue = 1;
    self.continuous = NO;
    
    self.on = NO;
    self.value = 0.0;
    
    self.clippingView = [[UIView alloc] initWithFrame:CGRectMake(4,2,87,23)];
    self.clippingView.clipsToBounds = YES;
    self.clippingView.userInteractionEnabled = NO;
    self.clippingView.backgroundColor = [UIColor clearColor];
    [self addSubview:self.clippingView];
    [self.clippingView release];
    
    NSString *leftLabelText = NSLocalizedString(@"ON","Custom UISwitch ON label. If localized to empty string then I/O will be used");
    if ([leftLabelText length] == 0)    
    {
        leftLabelText = @"l";        // use helvetica lowercase L to be a 1. 
    }
    
    self.leftLabel = [[UILabel alloc] init];
    self.leftLabel.frame = CGRectMake(0, 0, 48, 23);
    self.leftLabel.text = leftLabelText;
    self.leftLabel.textAlignment = NSTextAlignmentCenter;
    self.leftLabel.font = [UIFont boldSystemFontOfSize:17];
    self.leftLabel.textColor = [UIColor whiteColor];
    self.leftLabel.backgroundColor = [UIColor clearColor];
    //        self.leftLabel.shadowColor = [UIColor redColor];
    //        self.leftLabel.shadowOffset = CGSizeMake(0,0);
    [self.clippingView addSubview:self.leftLabel];
    [self.leftLabel release];
    
    
    NSString *rightLabelText = NSLocalizedString(@"OFF","Custom UISwitch OFF label. If localized to empty string then I/O will be used");
    if ([rightLabelText length] == 0)    
    {
        rightLabelText = @"O";    // use helvetica uppercase o to be a 0. 
    }
    
    self.rightLabel = [[UILabel alloc] init];
    self.rightLabel.frame = CGRectMake(95, 0, 48, 23);
    self.rightLabel.text = rightLabelText;
    self.rightLabel.textAlignment = NSTextAlignmentCenter;
    self.rightLabel.font = [UIFont boldSystemFontOfSize:17];
    self.rightLabel.textColor = [UIColor grayColor];
    self.rightLabel.backgroundColor = [UIColor clearColor];
    //        self.rightLabel.shadowColor = [UIColor redColor];
    //        self.rightLabel.shadowOffset = CGSizeMake(0,0);
    [self.clippingView addSubview:self.rightLabel];
    [self.rightLabel release];
    
    
}

-(void)layoutSubviews
{
    [super layoutSubviews];
    
    //    NSLog(@"leftLabel=%@",NSStringFromCGRect(self.leftLabel.frame));
    
    // move the labels to the front
    [self.clippingView removeFromSuperview];
    [self addSubview:self.clippingView];
    
    CGFloat thumbWidth = self.currentThumbImage.size.width;
    CGFloat switchWidth = self.bounds.size.width;
    CGFloat labelWidth = switchWidth - thumbWidth;
    CGFloat inset = self.clippingView.frame.origin.x;
    
    //    NSInteger xPos = self.value * (self.bounds.size.width - thumbWidth) - (self.leftLabel.frame.size.width - thumbWidth/2); 
    NSInteger xPos = self.value * labelWidth - labelWidth - inset;
    self.leftLabel.frame = CGRectMake(xPos, 0, labelWidth, 23);
    
    //    xPos = self.value * (self.bounds.size.width - thumbWidth) + (self.rightLabel.frame.size.width - thumbWidth/2); 
    xPos = switchWidth + (self.value * labelWidth - labelWidth) - inset; 
    self.rightLabel.frame = CGRectMake(xPos, 0, labelWidth, 23);
    
    //    NSLog(@"value=%f    xPos=%i",self.value,xPos);
    //    NSLog(@"thumbWidth=%f    self.bounds.size.width=%f",thumbWidth,self.bounds.size.width);
}

- (UIImage *)image:(UIImage*)image tintedWithColor:(UIColor *)tint 
{    
    
    if (tint != nil) 
    {
        UIGraphicsBeginImageContext(image.size);
        
        //draw mask so the alpha is respected
        CGContextRef currentContext = UIGraphicsGetCurrentContext();
        CGImageRef maskImage = [image CGImage];
        CGContextClipToMask(currentContext, CGRectMake(0, 0, image.size.width, image.size.height), maskImage);
        CGContextDrawImage(currentContext, CGRectMake(0,0, image.size.width, image.size.height), image.CGImage);
        
        [image drawAtPoint:CGPointMake(0,0)];
        [tint setFill];
        UIRectFillUsingBlendMode(CGRectMake(0,0,image.size.width,image.size.height),kCGBlendModeColor);
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
        return newImage;
    }
    else 
    {
        return image;
    }
}



-(void)setTintColor:(UIColor*)color
{
    if (color != tintColor)
    {
        [tintColor release];
        tintColor = [color retain];
        
        [self setMinimumTrackImage:[self image:[UIImage imageNamed:@"switchBlueBg.png"] tintedWithColor:tintColor] forState:UIControlStateNormal];
    }
    
}

- (void)setOn:(BOOL)turnOn animated:(BOOL)animated;
{
    on = turnOn;
    
    if (animated)
    {
        [UIView     beginAnimations:nil context:nil];
        [UIView setAnimationDuration:0.2];
    }
    
    if (on)
    {
        self.value = 1.0;
    }
    else 
    {
        self.value = 0.0;
    }
    
    if (animated)
    {
        [UIView    commitAnimations];    
    }
}

- (void)setOn:(BOOL)turnOn
{
    [self setOn:turnOn animated:NO];
}


- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    NSLog(@"preendTrackingWithtouch");
    [super endTrackingWithTouch:touch withEvent:event];
    NSLog(@"postendTrackingWithtouch");
    m_touchedSelf = YES;
    
    [self setOn:on animated:YES];
}

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
    [super touchesBegan:touches withEvent:event];
        NSLog(@"touchesBegan");
    m_touchedSelf = NO;
    on = !on;
}

- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
    [super touchesEnded:touches withEvent:event];
    NSLog(@"touchesEnded");
    
    if (!m_touchedSelf)
    {
        [self setOn:on animated:YES];
        [self sendActionsForControlEvents:UIControlEventValueChanged];
    }
}

-(void)dealloc
{
    [tintColor release];
    [clippingView release];
    [rightLabel release];
    [leftLabel release];
    
    [super dealloc];
}

@end

看代码可以知道,其实它是通过继承UISlider控件实现的,UISlider的左右分别是个UILabel,当YES的时候,滑块滑到了最右边,NO的时候滑到了最左边。

如何在代码中使用它呢?很简单:

- (void)loadView
{
    UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
    self.view = contentView;
    contentView.backgroundColor = [UIColor whiteColor];
    
    // Standard ON/OFF
    HMCustomSwitch *switchView = [[HMCustomSwitch alloc] initWithFrame:CGRectZero];
    switchView.center = CGPointMake(160.0f, 20.0f);
    switchView.on = YES;
    [contentView addSubview:switchView];
    [switchView release];
    
    // Custom YES/NO
    switchView = [HMCustomSwitch switchWithLeftText:@"YES" andRight:@"NO"];
    switchView.center = CGPointMake(160.0f, 60.0f);
    switchView.on = YES;
    [contentView addSubview:switchView];
    
    // Custom font and color
    switchView = [HMCustomSwitch switchWithLeftText:@"Hello " andRight:@"ABC "];
    switchView.center = CGPointMake(160.0f, 100.0f);
    switchView.on = YES;
    [switchView.leftLabel setFont:[UIFont boldSystemFontOfSize:13.0f]];
    [switchView.rightLabel setFont:[UIFont italicSystemFontOfSize:15.0f]];
    [switchView.rightLabel setTextColor:[UIColor blueColor]];
    [contentView addSubview:switchView];
    
    // Multiple lines
    switchView = [HMCustomSwitch switchWithLeftText:@"Hello\nWorld" andRight:@"Bye\nWorld"];
    switchView.center = CGPointMake(160.0f, 140.0f);
    switchView.on = YES;
    switchView.tintColor = [UIColor orangeColor];
    switchView.leftLabel.font = [UIFont boldSystemFontOfSize:9.0f];
    switchView.rightLabel.font = [UIFont boldSystemFontOfSize:9.0f];
    switchView.leftLabel.numberOfLines = 2;
    switchView.rightLabel.numberOfLines = 2;
    switchView.leftLabel.lineBreakMode = NSLineBreakByWordWrapping;
    switchView.rightLabel.lineBreakMode = NSLineBreakByWordWrapping;
    [contentView addSubview:switchView];
    
    switchView = [[HMCustomSwitch alloc] init];
    switchView.center = CGPointMake(160.0f, 180.0f);
    switchView.on = YES;
    switchView.tintColor = [UIColor purpleColor];
    [contentView addSubview:switchView];
    [switchView release];
    
    switchView = [HMCustomSwitch switchWithLeftText:@"l" andRight:@"O"];
    switchView.center = CGPointMake(160.0f, 220.0f);
//    customSwitch.tintColor = [UIColor colorWithRed:125.f/255.f green:157.f/255.f blue:93.f/255.f alpha:1.0];
//    customSwitch.tintColor = [UIColor colorWithRed:125.f/255.f green:157.f/255.f blue:93.f/255.f alpha:1.0];
    [contentView addSubview:switchView];

    // Standard ON/OFF
    switchView = [[HMCustomSwitch alloc] init];
    switchView.center = CGPointMake(160.0f, 260.0f);
    switchView.tintColor = [UIColor colorWithRed:125.f/255.f green:157.f/255.f blue:93.f/255.f alpha:1.0];
    [switchView addTarget:self action:@selector(switchFlipped:) forControlEvents:UIControlEventValueChanged];
    [contentView addSubview:switchView];
    [switchView release];
    
    
    
    UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 420, 320, 40)];
    toolbar.tintColor = [UIColor colorWithRed:125.f/255.f green:157.f/255.f blue:93.f/255.f alpha:1.0];
    [contentView addSubview:toolbar];
    
    [contentView release];
}

-(void)switchFlipped:(HMCustomSwitch*)switchView
{
    NSLog(@"switchFlipped=%f  on:%@",switchView.value, (switchView.on?@"Y":@"N"));
    
}

代码下载地址: https://github.com/schelling/HMCustomSwitch

容芳志 (http://blog.csdn.net/totogo2010)

本文遵循“署名-非商业用途-保持一致”创作公用协议

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
GoJS API学习
varnode{};node"key""节点Key";node"loc""00";//节点坐标node"text""节点名称";//添加节点通过按钮点击,添加新的节点到画布myDiagram.model.addNodeData(nod
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Android蓝牙连接汽车OBD设备
//设备连接public class BluetoothConnect implements Runnable {    private static final UUID CONNECT_UUID  UUID.fromString("0000110100001000800000805F9B34FB");
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
2个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这