最近收到产品经理的奇葩需求,实现一个选择笔迹粗细的功能,一边粗一边细,可以点击,可以拖拽,拖拽时随着进度变化,进度条和拖拽按钮的大小也随之变化,如下图:
恶不恶心?怎么实现? 绘制吗,太复杂了. 简单实现思路:
灰色背景条和随进度变化的彩色条都是ImageView
灰色背景上添加状态按钮
单独添加一个彩色按钮ImageView
彩色条随着彩色按钮ImageView变化
用到的素材 :
下面是代码 :
// ------------- SelectSliderView.h
#import <UIKit/UIKit.h>
@interface SelectSliderView : UIView
// 获取下标
- (void)selectSliderCurrentIndex:(void (^) (NSInteger index)) index;
// 设置下标
- (void)selectSliderSetCurrentIndex:(NSInteger) index;
@end
// ------------- SelectSliderView.m
#define c_begin_h 5 //changeImg初始高度
#define c_end_h 15 //changeImg最终高度
#define t_begin_h 9 //thumbImg初始高度
#define t_end_h 23 //thumbImg最终高度
#define b_count 5 //按钮个数
#import "SelectSliderView.h"
#import "UIView+Extension.h"
@interface SelectSliderView()
@property (nonatomic,strong) NSMutableArray <UIButton *> *buttons;
@property (nonatomic,strong) UIImageView *changeImgView;
@property (nonatomic,strong) UIImageView *thumbImgView;
@property (nonatomic,strong) void (^currentIndex)(NSInteger index);
@end
@implementation SelectSliderView
- (instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
[self customView];
}
return self;
}
- (void)customView{
// 背景灰色条
UIImageView *bgImgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"draw_line5"]];
bgImgView.frame = CGRectMake(0, (self.height-c_end_h)/2, self.width-1, c_end_h);
[self addSubview:bgImgView];
// 前景变化条 跟随thumbImgView变化
UIImageView *changeImgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"draw_line4"]];
changeImgView.frame = CGRectMake(0, 0, t_begin_h/2, t_begin_h);
changeImgView.centerY = self.height/2;
[self addSubview:changeImgView];
self.changeImgView = changeImgView;
CGFloat count = b_count -1;
// 创建按钮
for (int i = 0; i <= count; i++) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setImage:[UIImage imageNamed:@"draw_circleN5"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:@"draw_circleS5"] forState:UIControlStateSelected];
[button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
// 看不懂? 参考changeImgView进度变化
CGFloat W = (t_end_h-t_begin_h)/self.width * i * (self.width-t_end_h)/count;
button.frame = CGRectMake(i*(self.width-t_end_h)/count, 0, t_begin_h+W, t_begin_h+W);
button.centerY = self.height/2;
[self addSubview:button];
[self.buttons addObject:button];
}
// 拖拽的按钮
UIImageView *thumbImgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"draw_circleS5"]];
thumbImgView.frame = CGRectMake(0, (self.height-t_begin_h)/2, t_begin_h, t_begin_h);
thumbImgView.userInteractionEnabled = YES;
[self addSubview:thumbImgView];
self.thumbImgView = thumbImgView;
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(thumbImgPan:)];
[self.thumbImgView addGestureRecognizer:pan];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(thumbImgTap:)];
[self.thumbImgView addGestureRecognizer:tap];
}
- (void)thumbImgPan:(UIPanGestureRecognizer *)sender{
CGPoint point = [sender translationInView:self.thumbImgView];
sender.view.transform = CGAffineTransformTranslate(sender.view.transform, point.x, 0);
[sender setTranslation:CGPointZero inView:sender.view];
// 限制出界
if (self.thumbImgView.x < 0) self.thumbImgView.x = 0;
if (CGRectGetMaxX(self.thumbImgView.frame) > self.width) self.thumbImgView.x = self.width - CGRectGetWidth(self.thumbImgView.frame);
[self thumbImageViewAuto];
[self changeImageViewAuto];
[self setButtonStatus];
if (sender.state == UIGestureRecognizerStateEnded) {
[self jumpToButtonWithX:self.thumbImgView.x];
}
}
- (void)thumbImgTap:(UITapGestureRecognizer *)sender{
for (int i = 0; i < _buttons.count; i++) {
UIButton *button = _buttons[I];
if (_thumbImgView.x == button.x) {
if (self.currentIndex) {
self.currentIndex(i);
}
}
}
}
- (void)selectSliderCurrentIndex:(void (^)(NSInteger))index{
_currentIndex = index;
}
- (void)selectSliderSetCurrentIndex:(NSInteger) index{
for (int i = 0; i < _buttons.count; i++) {
if (index == i) {
UIButton *button = _buttons[I];
_thumbImgView.x = button.x;
[self thumbImageViewAuto];
[self changeImageViewAuto];
[self setButtonStatus];
}
}
}
// 点击按钮
- (void)buttonAction:(UIButton *)sender{
for (int i = 0; i < _buttons.count; i++) {
UIButton *button = _buttons[I];
if (sender == button) {
[UIView animateWithDuration:0.25 animations:^{
_thumbImgView.x = button.x;
[self thumbImageViewAuto];
[self changeImageViewAuto];
[self setButtonStatus];
}completion:^(BOOL finished) {
button.selected = YES;
if (self.currentIndex) {
self.currentIndex(i);
}
}];
}
}
}
// 如果滑动到两按钮之间,自动跳转到button位置
- (void)jumpToButtonWithX:(CGFloat)thumbX{
CGFloat minW = self.width/((b_count-1)*2);
for (int i = 0; i < self.buttons.count; i++) {
UIButton *button = self.buttons[I];
if (button.x-minW < thumbX && thumbX < button.x+minW) {
[UIView animateWithDuration:0.15 animations:^{
_thumbImgView.x = button.x;
[self changeImageViewAuto];
}completion:^(BOOL finished) {
button.selected = YES;
if (self.currentIndex) {
self.currentIndex(i);
}
}];
}
}
}
// button状态
- (void)setButtonStatus{
for (int i = 0; i < self.buttons.count; i++) {
UIButton *button = self.buttons[I];
if (button.x <= self.thumbImgView.x) {
button.selected = YES;
}else{
button.selected = NO;
}
}
}
// thumb变化
- (void)thumbImageViewAuto{
CGFloat thumb_w = t_begin_h + (t_end_h-t_begin_h)/self.width * self.thumbImgView.x;
self.thumbImgView.size = CGSizeMake(thumb_w,thumb_w);
self.thumbImgView.centerY = self.height/2;
}
// 进度随thumbImgView变化 同时改变宽高
- (void)changeImageViewAuto{
self.changeImgView.size = CGSizeMake(self.thumbImgView.width/2+self.thumbImgView.x, c_begin_h+(c_end_h-c_begin_h)/self.width*self.thumbImgView.x);
self.changeImgView.centerY = self.height/2;
}
- (NSMutableArray<UIButton *> *)buttons{
if (!_buttons) {
_buttons = [[NSMutableArray alloc] init];;
}
return _buttons;
}
@end
是的就这么点代码就这么简单, 是不是豁然开朗, 嘎嘎嘎....