iOS每日一记之———————————————自定义UIswitch 控件

廉高邈
2023-12-01

看了好多自定义switch控件的demo  大多用UIview + label +imageView 实现的 还有用UIsilder实现的 感觉都不是特别满意 

遂  自己写个一个 可以设置开关状态 BOOL isOn;

点击也可以触发valueChanged方法 简单粗暴

控件 继承与UIcontrol

OK 接下来上代码。。。

ZHSwitch的。h文件如下

#import <UIKit/UIKit.h>

@interface ZHSwitch : UIControl
{
    // private member
    BOOL m_touchedSelf;
    
    BOOL on;

    
}
@property (nonatomic, assign, getter = isOn) BOOL on;
@property (nonatomic, strong) UIColor *onTintColor;
@property (nonatomic, strong) UIColor *tintColor;
@property (nonatomic, strong) UIColor *thumbTintColor;
@property (nonatomic, assign) NSInteger switchKnobSize;
@property (nonatomic, strong) UIColor *textColor;
@property (nonatomic, strong) UIFont *textFont;

@property (nonatomic, strong) NSString *onText;
@property (nonatomic, strong) NSString *offText;
@property (nonatomic, strong) UIView *onContentView;
/** 显示状态背景View */
@property (nonatomic,strong)  UIImageView *onContentBgView;
@property (nonatomic, strong) UIView *offContentView;
/** 关闭状态背景View */
@property (nonatomic,strong)  UIImageView *offContentBgView;
//款间距
@property (nonatomic, assign) NSInteger ballWithSize;
//竖着的间距
@property (nonatomic, assign) NSInteger ballHightSize;

@property (nonatomic,assign) NSInteger ballSize;
@property (nonatomic, strong) UIView *knobView;
/** 中间按钮背景View */
@property (nonatomic,strong)  UIImageView *knobBgView;


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

- (id)initWithFrame:(CGRect)frame
            onColor:(UIColor *)onColor
           offColor:(UIColor *)offColor
               font:(UIFont *)font
           ballSize:(NSInteger )ballSize
 onContentBgViewStr:(NSString *)onContentBgViewStr
offContentBgViewStr:(NSString *)offContentBgViewStr
      knobBgViewStr:(NSString *)knobBgViewStr;






#import "ZHSwitch.h"
#define ZHSwitchMaxHeight 80.0f
#define ZHSwitchMinHeight 20.0f

#define ZHSwitchMinWidth 40.0f


@interface ZHSwitch ()
@property (nonatomic, strong) UIView *containerView;
@property (nonatomic, strong) UIColor *onColor;
@property (nonatomic, strong) UIFont * font;
@property (nonatomic, strong) UIColor *offColor;
@property (nonatomic, strong) UILabel *onLabel;
@property (nonatomic, strong) UILabel *offLabel;
/** 显示状态背景图名字 */
@property (nonatomic,copy)NSString *onContentBgViewStr;
/** 关闭状态背景图名字  */
@property (nonatomic,copy)NSString *offContentBgViewStr;
/** 中间状态背景图名字  */
@property (nonatomic,copy)NSString *knobBgViewStr;

- (void)commonInit;

- (CGRect)roundRect:(CGRect)frameOrBounds;
@end

@implementation ZHSwitch
- (id)initWithFrame:(CGRect)frame
            onColor:(UIColor *)onColor
           offColor:(UIColor *)offColor
               font:(UIFont *)font
           ballSize:(NSInteger )ballSize
 onContentBgViewStr:(NSString *)onContentBgViewStr
offContentBgViewStr:(NSString *)offContentBgViewStr
      knobBgViewStr:(NSString *)knobBgViewStr
{
    self = [super initWithFrame:[self roundRect:frame]];
    if (self) {
        self.ballSize = ballSize;
        self.font = font;
        self.onColor = onColor;
        self.offColor = offColor;
        self.onContentBgViewStr = onContentBgViewStr;
        self.offContentBgViewStr = offContentBgViewStr;
        self.knobBgViewStr = knobBgViewStr;
        [self commonInit];
    }
    return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    
    if (self) {
        [self commonInit];
    }
    
    return self;
}

- (void)setBounds:(CGRect)bounds
{
    [super setBounds:[self roundRect:bounds]];
    
    [self setNeedsLayout];
}

- (void)setFrame:(CGRect)frame
{
    [super setFrame:[self roundRect:frame]];
    
    [self setNeedsLayout];
}

- (void)setOnText:(NSString *)onText
{
    if (_onText != onText) {
        _onText = onText;
        
        _onLabel.text = onText;
    }
}

- (void)setOffText:(NSString *)offText
{
    if (_offText != offText) {
        _offText = offText;
        
        _offLabel.text = offText;
    }
}

- (void)setOnTintColor:(UIColor *)onTintColor
{
    if (_onTintColor != onTintColor) {
        _onTintColor = onTintColor;
        
        _onContentView.backgroundColor = onTintColor;
    }
}

- (void)setTintColor:(UIColor *)tintColor
{
    if (_tintColor != tintColor) {
        _tintColor = tintColor;
        
        _offContentView.backgroundColor = tintColor;
    }
}

- (void)setThumbTintColor:(UIColor *)thumbTintColor
{
    if (_thumbTintColor != thumbTintColor) {
        _thumbTintColor = thumbTintColor;
        
        _knobView.backgroundColor = _thumbTintColor;
    }
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    self.containerView.frame = self.bounds;
    
    CGFloat r = CGRectGetHeight(self.containerView.bounds) / 2.0;
    
    self.containerView.layer.cornerRadius = r;
    self.containerView.layer.masksToBounds = YES;
    
    CGFloat margin = (CGRectGetHeight(self.bounds) - self.ballSize) / 2.0;
    
    
 
    if (!on) {
        // frame of off status
        self.onContentView.frame = CGRectMake(-1 * CGRectGetWidth(self.containerView.bounds),
                                              0,
                                              CGRectGetWidth(self.containerView.bounds),
                                              CGRectGetHeight(self.containerView.bounds));
        
        self.offContentView.frame = CGRectMake(0,
                                               0,
                                               CGRectGetWidth(self.containerView.bounds),
                                               CGRectGetHeight(self.containerView.bounds));
        
        self.knobView.frame = CGRectMake(margin,
                                         margin,
                                         self.ballSize,
                                         self.ballSize);
    } else {
        // frame of on status
        self.onContentView.frame = CGRectMake(0,
                                              0,
                                              CGRectGetWidth(self.containerView.bounds),
                                              CGRectGetHeight(self.containerView.bounds));
        
        self.offContentView.frame = CGRectMake(0,
                                               CGRectGetWidth(self.containerView.bounds),
                                               CGRectGetWidth(self.containerView.bounds),
                                               CGRectGetHeight(self.containerView.bounds));
        
        self.knobView.frame = CGRectMake(CGRectGetWidth(self.containerView.bounds) - margin - self.ballSize,
                                         margin,
                                         self.ballSize,
                                         self.ballSize);
    }
    
    CGFloat lHeight = 20.0f;
    CGFloat lMargin = r - (sqrtf(powf(r, 2) - powf(lHeight / 2.0, 2))) + margin;
    
    self.onLabel.frame = CGRectMake(lMargin,
                                    r - lHeight / 2.0,
                                    CGRectGetWidth(self.onContentView.bounds) - lMargin - self.ballSize - 2 * margin,
                                    lHeight);
    
    self.offLabel.frame = CGRectMake(self.ballSize + 2 * margin,
                                     r - lHeight / 2.0,
                                     CGRectGetWidth(self.onContentView.bounds) - lMargin - self.ballSize - 2 * margin,
                                     lHeight);
    
     _on = on;
}
- (void)setOn:(BOOL)turnOn
{
    [self setOn:turnOn animated:NO];
}
- (void)setOn:(BOOL)turnOn animated:(BOOL)animated{
    
    on = turnOn;
 
    CGFloat margin = (CGRectGetHeight(self.bounds) - self.ballSize) / 2.0;
    if (!animated) {
        if (!on) {
            // frame of off status
            self.onContentView.frame = CGRectMake(-1 * CGRectGetWidth(self.containerView.bounds),
                                                  0,
                                                  CGRectGetWidth(self.containerView.bounds),
                                                  CGRectGetHeight(self.containerView.bounds));
            
            self.offContentView.frame = CGRectMake(0,
                                                   0,
                                                   CGRectGetWidth(self.containerView.bounds),
                                                   CGRectGetHeight(self.containerView.bounds));
            
            self.knobView.frame = CGRectMake(margin,
                                             margin,
                                             self.ballSize,
                                             self.ballSize);
        } else {
            // frame of on status
            self.onContentView.frame = CGRectMake(0,
                                                  0,
                                                  CGRectGetWidth(self.containerView.bounds),
                                                  CGRectGetHeight(self.containerView.bounds));
            
            self.offContentView.frame = CGRectMake(0,
                                                   CGRectGetWidth(self.containerView.bounds),
                                                   CGRectGetWidth(self.containerView.bounds),
                                                   CGRectGetHeight(self.containerView.bounds));
            
            self.knobView.frame = CGRectMake(CGRectGetWidth(self.containerView.bounds) - margin - self.ballSize,
                                             margin,
                                             self.ballSize,
                                             self.ballSize);
        }
    } else {
        if (on) {
            [UIView animateWithDuration:0.25
                             animations:^{
                                 self.knobView.frame = CGRectMake(CGRectGetWidth(self.containerView.bounds) - margin - self.ballSize,
                                                                  margin,
                                                                  self.ballSize,
                                                                  self.ballSize);
                             }
                             completion:^(BOOL finished){
                                 self.onContentView.frame = CGRectMake(0,
                                                                       0,
                                                                       CGRectGetWidth(self.containerView.bounds),
                                                                       CGRectGetHeight(self.containerView.bounds));
                                 
                                 self.offContentView.frame = CGRectMake(0,
                                                                        CGRectGetWidth(self.containerView.bounds),
                                                                        CGRectGetWidth(self.containerView.bounds),
                                                                        CGRectGetHeight(self.containerView.bounds));
                             }];
        } else {
            [UIView animateWithDuration:0.25
                             animations:^{
                                 self.knobView.frame = CGRectMake(margin,
                                                                  margin,
                                                                  self.ballSize,
                                                                  self.ballSize);
                             }
                             completion:^(BOOL finished){
                                 self.onContentView.frame = CGRectMake(-1 * CGRectGetWidth(self.containerView.bounds),
                                                                       0,
                                                                       CGRectGetWidth(self.containerView.bounds),
                                                                       CGRectGetHeight(self.containerView.bounds));
                                 
                                 self.offContentView.frame = CGRectMake(0,
                                                                        0,
                                                                        CGRectGetWidth(self.containerView.bounds),
                                                                        CGRectGetHeight(self.containerView.bounds));
                             }];
        }
    }

       _on = on;
}
#pragma mark - Private API

- (void)commonInit
{
    self.backgroundColor = [UIColor clearColor];
    
    _onTintColor = self.onColor;
    _tintColor = self.offColor;
    if ([_knobBgViewStr isEqualToString:@""] || _knobBgViewStr == nil) {
        _thumbTintColor = [UIColor colorWithWhite:1 alpha:1];
    } else{
    _thumbTintColor = [UIColor clearColor];
    }
    
    _textFont = self.font;
    _textColor = [UIColor whiteColor];
    
    _containerView = [[UIView alloc] initWithFrame:self.bounds];
    _containerView.backgroundColor = [UIColor clearColor];
    [self addSubview:_containerView];
    
    _onContentView = [[UIView alloc] initWithFrame:self.bounds];
    _onContentView.backgroundColor = _onTintColor;
    [_containerView addSubview:_onContentView];
    
    _onContentBgView =[[UIImageView alloc]init];
    _onContentBgView.image =[UIImage imageNamed:self.onContentBgViewStr];
    _onContentBgView.frame = _onContentView.bounds;
    _onContentBgView.contentMode = UIViewContentModeScaleAspectFit;
    [_onContentView addSubview:_onContentBgView];
    
    _offContentView = [[UIView alloc] initWithFrame:self.bounds];
    _offContentView.backgroundColor = _tintColor;
    [_containerView addSubview:_offContentView];
    
    _offContentBgView =[[UIImageView alloc]init];
    _offContentBgView.image =[UIImage imageNamed:self.offContentBgViewStr];
    _offContentBgView.frame = _offContentView.bounds;
    _offContentBgView.contentMode = UIViewContentModeScaleAspectFit;
    [_offContentView addSubview:_offContentBgView];
    
    _knobView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.ballSize, self.ballSize)];
    _knobView.backgroundColor = _thumbTintColor;
    _knobView.layer.cornerRadius = self.ballSize / 2.0;
   [_containerView addSubview:_knobView];
    
    _knobBgView =[[UIImageView alloc]init];
    _knobBgView.image =[UIImage imageNamed:self.knobBgViewStr];
    _knobBgView.frame = _knobView.bounds;
    _knobBgView.contentMode = UIViewContentModeScaleAspectFit;
    [_knobView addSubview:_knobBgView];
   
    _onLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    _onLabel.backgroundColor = [UIColor clearColor];
    _onLabel.textAlignment = NSTextAlignmentCenter;
    _onLabel.textColor = _textColor;
    _onLabel.font = _font;
    _onLabel.text = _onText;
    [_onContentView addSubview:_onLabel];
    
    _offLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    _offLabel.backgroundColor = [UIColor clearColor];
    _offLabel.textAlignment = NSTextAlignmentCenter;
    _offLabel.textColor = _textColor;
    _offLabel.font = _font;
    _offLabel.text = _offText;
    [_offContentView addSubview:_offLabel];

}

- (CGRect)roundRect:(CGRect)frameOrBounds
{
    CGRect newRect = frameOrBounds;
    
    if (newRect.size.height > ZHSwitchMaxHeight) {
        newRect.size.height = ZHSwitchMaxHeight;
    }
    
    if (newRect.size.height < ZHSwitchMinHeight) {
        newRect.size.height = ZHSwitchMinHeight;
    }
    
    if (newRect.size.width < ZHSwitchMinWidth) {
        newRect.size.width = ZHSwitchMinWidth;
    }
    
    return newRect;
}
- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    
    
    [super endTrackingWithTouch:touch withEvent:event];
   
    m_touchedSelf = YES;
    
    [self setOn:on animated:YES];
}
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
    
    [super touchesBegan:touches withEvent:event];
    
    m_touchedSelf = NO;
    on = !on;
}
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
    
    [super touchesEnded:touches withEvent:event];

    
    if (!m_touchedSelf)
    {
        [self setOn:on animated:YES];
        [self sendActionsForControlEvents:UIControlEventValueChanged];
    }
}
@end




 类似资料: