服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - iOS实现垂直滑动条效果

iOS实现垂直滑动条效果

2022-08-01 11:41hzgisme IOS

这篇文章主要为大家详细介绍了iOS实现垂直滑动条效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

我们知道在 iOS 开发中,有一个控件经常用到,那就是滑动条(UISlider),可以满足我们滑动取值的需求。但是现在有一个需求,就是需要一个垂直的滑动条,而 UISlider 并不能设置为垂直滑动,所以我们就需要自己定义一个控件来实现垂直的要求。

整理之后,我们可以得出需要以下的基本需求:

  • 可以上下滑动
  • 按钮可以自定义图片
  • 可以设置最小值
  • 可以设置最大值
  • 可以在滑动过程中获取实时的值
  • 可以在滑动结束时获取到最终的值
  • 可以设置进度背景色

我们的实现原理就是实现一个自定义的 UIView,然后在上面添加需要用到的控件,对控件添加一定的手势功能,从而实现垂直滑动。实现了一个单独的类,功能不多,但是能满足以上基本的需求,代码如下,代码中用到的宏可以自行替换,开箱即用,简单明了:

VerticalSlider.h

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//
//  VerticalSlider.h
//  
//
//  Created by huang zhengguo on 2019/8/30.
//  Copyright © 2019 huang zhengguo . 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 progressColor 进度颜色
 * @param thumImage 滑动按钮背景
 *
 * @return 垂直滑动条
 *
 */
- (instancetype)initWithFrame:(CGRect)frame title:(NSString *)title progressColor:(UIColor *)progressColor thumImage:(NSString *)thumImage;
 
@end
 
NS_ASSUME_NONNULL_END

VerticalSlider.m

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
//
//  VerticalSlider.m
// 
//
//  Created by huang zhengguo on 2019/8/30.
//  Copyright © 2019 zhengguohuang. 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 progressColor:(UIColor *)progressColor 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 = [progressColor colorWithAlphaComponent:0.3];
        self.backLabel.translatesAutoresizingMaskIntoConstraints = NO;
 
        [self addSubview:self.backLabel];
 
        self.progressLabel = [[UILabel alloc] init];
 
        self.progressLabel.backgroundColor = progressColor;
        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(0, 0) 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) * (1 - 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 * 100];
}
 
- (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) * (1 - 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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/hzgisme/article/details/116017885

延伸 · 阅读

精彩推荐
  • IOSIOS开发实现手机震动的提示实例代码

    IOS开发实现手机震动的提示实例代码

    这篇文章主要介绍了IOS开发实现手机震动的提示实例代码的相关资料,需要的朋友可以参考下...

    iOS开发网8312021-03-13
  • IOSIOS代码笔记之仿电子书书架效果

    IOS代码笔记之仿电子书书架效果

    这篇文章主要为大家详细介绍了IOS仿电子书书架效果的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    iOS开发网10182021-01-21
  • IOSiOS开发实现简单计算器功能

    iOS开发实现简单计算器功能

    这篇文章主要为大家详细介绍了iOS开发实现简单计算器功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    Qu_qipa5172022-07-29
  • IOSiOS11Xcode9打包注意事项

    iOS11Xcode9打包注意事项

    这篇文章主要介绍了iOS11&iPhoneX适配&Xcode9打包注意事项,需要的朋友可以参考下...

    iOS开发网4482021-04-02
  • IOS快速上手IOS UIBezierPath(贝塞尔曲线)

    快速上手IOS UIBezierPath(贝塞尔曲线)

    本文主要介绍了IOS 贝塞尔曲线(UIBezierPath)的基础知识。具有很好的参考价值。下面跟着小编一起来看下吧...

    洛洛爱吃肉9092021-03-10
  • IOSiOS如何巧妙解决NSTimer的循环引用详解

    iOS如何巧妙解决NSTimer的循环引用详解

    这篇文章主要给大家介绍了关于iOS如何巧妙解决NSTimer的循环引用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学...

    恩说吧12312021-04-22
  • IOSiOS UIImageView图片自动拉伸功能

    iOS UIImageView图片自动拉伸功能

    这篇文章主要介绍了iOS UIImageView图片自动拉伸功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    plus11442021-03-02
  • IOSiOS开发之TextField禁用粘贴、选择和全选功能

    iOS开发之TextField禁用粘贴、选择和全选功能

    这篇文章主要为大家详细介绍了iOS开发之TextField禁用粘贴、选择和全选功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    chernyog12392021-03-29