iSO垂直滑动条VerticalSlider

2023-06-12,,

由于项目需要实现一个垂直的Slider,滑动条使用UIlabel实现,按钮使用UIButton,按钮可以设置背景图片,代码如下

VerticalSlider.h

//
// VerticalSlider.h
// EXOTerra
//
// Created by huang zhengguo on 2019/8/30.
// Copyright © 2019 Inledco. All rights reserved.
// #import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN @interface VerticalSlider : UIView @property (assign, nonatomic) float value;
@property (strong, nonatomic) UIImage *thumImage;
@property (assign, nonatomic) float minimumValue;
@property (assign, nonatomic) float maximumValue; @property (copy, nonatomic) void (^passValue) (float);
@property (copy, nonatomic) void (^passEndValue) (float); /**
* 初始化滑动条
*
* @param frame 大小
* @param title 标题
* @param thumImage 滑动按钮背景
*
* @return 垂直滑动条
*
*/
- (instancetype)initWithFrame:(CGRect)frame title:(NSString *)title thumImage:(NSString *)thumImage; @end NS_ASSUME_NONNULL_END

VerticalSlider.m

//
// VerticalSlider.m
// EXOTerra
//
// Created by huang zhengguo on 2019/8/30.
// Copyright © 2019 Inledco. All rights reserved.
// #import "VerticalSlider.h" #define THUM_BTN_WIDTH 30.0
#define THUM_BTN_HEIGHT 50.0 @interface VerticalSlider() @property (strong, nonatomic) UIButton *thumBtn;
// 使用两个label表示进度,一个背景,一个进度
@property (strong, nonatomic) UILabel *backLabel;
@property (strong, nonatomic) UILabel *progressLabel;
// 底部标题
@property (strong, nonatomic) UILabel *titleLabel;
// 值标题
@property (strong, nonatomic) UILabel *valueLabel; @end @implementation VerticalSlider - (instancetype)initWithFrame:(CGRect)frame title:(NSString *)title thumImage:(NSString *)thumImage {
if (self = [super initWithFrame:frame]) {
// 滑动按钮
self.thumBtn = [[UIButton alloc] init]; [self.thumBtn setBackgroundImage:[UIImage imageNamed:thumImage] forState:UIControlStateNormal];
self.thumBtn.translatesAutoresizingMaskIntoConstraints = NO; UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(thumbPanAction:)]; [self.thumBtn addGestureRecognizer:panGestureRecognizer];
[self addSubview:self.thumBtn]; // 进度条
self.backLabel = [[UILabel alloc] init]; self.backLabel.backgroundColor = [UIColor darkGrayColor];
self.backLabel.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:self.backLabel]; self.progressLabel = [[UILabel alloc] init]; self.progressLabel.backgroundColor = [UIColor blueColor];
self.progressLabel.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:self.progressLabel]; // 底部标题
self.titleLabel = [[UILabel alloc] init]; self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.titleLabel.textAlignment = NSTextAlignmentCenter;
self.titleLabel.textColor = [UIColor whiteColor];
self.titleLabel.text = title; [self addSubview:self.titleLabel]; // 顶部值
self.valueLabel = [[UILabel alloc] init]; self.valueLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.valueLabel.textAlignment = NSTextAlignmentCenter;
self.valueLabel.textColor = [UIColor whiteColor]; [self addSubview:self.valueLabel]; [self bringSubviewToFront:self.thumBtn]; [self setConstraints]; // 初始化数据
self.value = 0.0;
} return self;
} #pragma mark --- 按钮拖动方法
- (void)thumbPanAction:(UIPanGestureRecognizer *)panGestureRecognizer {
// 转换坐标
CGPoint point = [panGestureRecognizer translationInView:self]; CGFloat yOriginPoint = panGestureRecognizer.view.frame.origin.y + point.y;
if (yOriginPoint >=self.backLabel.frame.origin.y && yOriginPoint <= (self.backLabel.frame.origin.y + self.backLabel.frame.size.height - THUM_BTN_HEIGHT)) {
panGestureRecognizer.view.frame = CGRectMake(panGestureRecognizer.view.frame.origin.x, panGestureRecognizer.view.frame.origin.y + point.y, THUM_BTN_WIDTH, THUM_BTN_HEIGHT); self.value = 1.0 - (yOriginPoint - self.backLabel.frame.origin.y) / (self.backLabel.frame.size.height - THUM_BTN_HEIGHT);
if (self.passValue) {
KMYLOG(@"colorValue = %f", self.value);
self.passValue(self.value);
}
} // 转换成原来坐标系的坐标
[panGestureRecognizer setTranslation:CGPointMake(, ) inView:self]; if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) {
if (self.passEndValue) {
KMYLOG(@"结束滑动");
// 转为字符串,又转为float,是为了去的两位小数的浮点数
self.passEndValue([[NSString stringWithFormat:@"%.2f", self.value] floatValue]);
}
}
} - (void)setValue:(float)value {
_value = value; self.thumBtn.frame = CGRectMake(self.thumBtn.frame.origin.x, (self.backLabel.frame.size.height - THUM_BTN_HEIGHT) * ( - value) + self.backLabel.frame.origin.y, THUM_BTN_WIDTH, THUM_BTN_HEIGHT);
self.progressLabel.frame = CGRectMake(self.progressLabel.frame.origin.x, self.thumBtn.frame.origin.y + THUM_BTN_HEIGHT, self.progressLabel.frame.size.width, self.backLabel.frame.origin.y + self.backLabel.frame.size.height - self.thumBtn.frame.origin.y - THUM_BTN_HEIGHT);
self.valueLabel.text = [NSString stringWithFormat:@"%.0f%%", value * ];
} - (void)setConstraints {
NSArray *titleLabelArray = @[self.titleLabel, self.valueLabel];
for (UILabel *label in titleLabelArray) {
NSLayoutConstraint *labelLeadingLayoutConstraint = [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0];
NSLayoutConstraint *labelTrailingLayoutConstraint = [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0.0];
NSLayoutConstraint *labelHeightLayoutConstraint = [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:30.0]; [self addConstraints:@[labelLeadingLayoutConstraint, labelTrailingLayoutConstraint, labelHeightLayoutConstraint]]; if (label == self.titleLabel) {
NSLayoutConstraint *labelBottomLayoutConstraint = [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]; [self addConstraint:labelBottomLayoutConstraint];
} else if (label == self.valueLabel) {
NSLayoutConstraint *labelTopLayoutConstraint = [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]; [self addConstraint:labelTopLayoutConstraint];
}
} NSArray *labelArray = @[self.backLabel, self.progressLabel];
for (UILabel *label in labelArray) {
NSLayoutConstraint *progressCenterXLayoutConstraint = [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0];
NSLayoutConstraint *progressBottomLayoutConstraint = [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.titleLabel attribute:NSLayoutAttributeTop multiplier:1.0 constant:-8.0];
NSLayoutConstraint *progressWidthLayoutConstraint = [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:3.0]; [self addConstraints:@[progressCenterXLayoutConstraint, progressBottomLayoutConstraint, progressWidthLayoutConstraint]]; if (label == self.backLabel) {
NSLayoutConstraint *progressTopLayoutConstraint = [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.valueLabel attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]; [self addConstraint:progressTopLayoutConstraint];
} else {
NSLayoutConstraint *progressHeightLayoutConstraint = [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:0.0]; [self addConstraint:progressHeightLayoutConstraint];
}
} NSLayoutConstraint *thumBtnCenterXLayoutConstraint = [NSLayoutConstraint constraintWithItem:self.thumBtn attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0];
NSLayoutConstraint *thumBtnBottomLayoutConstraint = [NSLayoutConstraint constraintWithItem:self.thumBtn attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.backLabel attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0];
NSLayoutConstraint *thumBtnWidthLayoutConstraint = [NSLayoutConstraint constraintWithItem:self.thumBtn attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:THUM_BTN_WIDTH];
NSLayoutConstraint *thumBtnHeightLayoutConstraint = [NSLayoutConstraint constraintWithItem:self.thumBtn attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:THUM_BTN_HEIGHT]; [self addConstraints:@[thumBtnCenterXLayoutConstraint, thumBtnBottomLayoutConstraint, thumBtnWidthLayoutConstraint, thumBtnHeightLayoutConstraint]];
} - (void)layoutSubviews {
[super layoutSubviews]; self.thumBtn.frame = CGRectMake(self.thumBtn.frame.origin.x, (self.backLabel.frame.size.height - THUM_BTN_HEIGHT) * ( - self.value) + self.backLabel.frame.origin.y, THUM_BTN_WIDTH, THUM_BTN_HEIGHT);
self.progressLabel.frame = CGRectMake(self.progressLabel.frame.origin.x, self.thumBtn.frame.origin.y + THUM_BTN_HEIGHT, self.progressLabel.frame.size.width, self.backLabel.frame.origin.y + self.backLabel.frame.size.height - self.thumBtn.frame.origin.y - THUM_BTN_HEIGHT);
} /*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/ @end

iSO垂直滑动条VerticalSlider的相关教程结束。

《iSO垂直滑动条VerticalSlider.doc》

下载本文的Word格式文档,以方便收藏与打印。