iOS 自定义滑动OYRSlider时间选择器

一:实现效果


二:实现思路


1:配置参数添加到ViewController

- (void)viewDidLoad {

[super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

[self addSliderBackView];

}

//添加滚动视图背景

-(void)addSliderBackView

{

UIImageView * sliderBackView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 64, self.view.bounds.size.width, 150)];

//    _sliderBackView.backgroundColor = [UIColor colorWithRed:0.733 green:0.920 blue:0.756 alpha:1.000];

sliderBackView.userInteractionEnabled = YES;

sliderBackView.backgroundColor = [UIColor yellowColor];//clearColor

[self.view addSubview:sliderBackView];

UILabel * signLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 20,200, 20)];

signLabel.backgroundColor = [UIColor clearColor];

signLabel.textColor = [UIColor colorWithWhite:0.560 alpha:1.000];

signLabel.font = [UIFont systemFontOfSize:18];

signLabel.text = @"持续时间";

[sliderBackView addSubview:signLabel];

/* tpl 使用方法 */

_rangeSlider = [[OYRSlider alloc] initWithFrame:CGRectMake(10,signLabel.frame.size.height + signLabel.frame.origin.y + 10, sliderBackView.frame.size.width - 10*2, sliderBackView.frame.size.height - signLabel.frame.size.height - 10)];

//    _rangeSlider.backgroundColor = [UIColor colorWithRed:0.676 green:1.000 blue:0.366 alpha:1.000];

_rangeSlider.backgroundColor = [UIColor clearColor];

[sliderBackView addSubview:_rangeSlider];

_rangeSlider.titleArray = @[@"30分钟",@"1小时",@"2小时",@"4小时",@"8小时",@"16小时",@"1天",@"2天",@"4天"];

_rangeSlider.titleHeight = 20;

_rangeSlider.titleFont = [UIFont systemFontOfSize:13];

_rangeSlider.sliderItemSize = 28;

//因为Slider是继承的UIControl,所以可以注册信息

[_rangeSlider addTarget:self action:@selector(valueChange:) forControlEvents:UIControlEventValueChanged];

/* tpl 使用方法 */

}

-(void)valueChange:(id)sender

{

OYRSlider * slider = (OYRSlider *)sender;

NSLog(@" -- valueChange -- %ld",(long)slider.rightItem.range);

}

2:自定义滑块 OYRSliderItem : UIImageView

@interface OYRSliderItem : UIImageView

@property(nonatomic,strong)void (^pan)(UIPanGestureRecognizer * pan ,int itemStyle,OYRSliderItem * item);

@property(nonatomic,assign)int itemStyle;//0为左边,1为右边

@property(nonatomic,assign)int range;

@end


3:自定义滑动区间 OYRSlider : UIControl

@interface OYRSlider : UIControl

@property(nonatomic,assign)CGFloat  titleHeight;//文字高度

@property(nonatomic,strong)NSArray * titleArray;//文字数组

@property(nonatomic,strong)UIColor * titleColor;//文字颜色

@property(nonatomic,strong)UIColor * titleSelectColor;//文字颜色

@property(nonatomic,strong)UIFont  * titleFont;//文字大小

//滑动块

@property(nonatomic,readonly)OYRSliderItem * rightItem;

//滑动条

@property(nonatomic,strong)UIColor * bottomColor;//底部颜色

@property(nonatomic,strong)UIColor * upColor;//滑动区域颜色

@property(nonatomic,assign)CGFloat sliderItemSize;//滑块的大小

@property(nonatomic,assign)CGFloat bottomViewHeight;//底部view的高

@property(nonatomic,assign)CGFloat upViewHeight;//上面的高

@end

三:github地址

https://github.com/ouyangrong1313/OYRSlidergithub地址

//

//  OYRSlider.m

//  OYRSlider

//

//  Created by 欧阳荣 on 17/4/5.

//  Copyright © 2017年 HengTaiXin. All rights reserved.

//

#import "OYRSlider.h"

#define dealocInfo NSLog(@"%@ 释放了",[self class])

#define baseColor [UIColor colorWithRed:0.389 green:0.670 blue:0.265 alpha:1.000]

@implementation OYRSliderItem

-(void)dealloc{

dealocInfo;

}

-(id)initWithFrame:(CGRect)frame

{

self = [super initWithFrame:frame];

if(self)

{

self.userInteractionEnabled = YES;

self.image = [UIImage imageNamed:@"btn_slide_pk"];

//添加手势

UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];

[self addGestureRecognizer:pan];

}

return self;

}

-(void)pan:(UIPanGestureRecognizer *)pan

{

if (self.pan)

{

typeof(self) __weak weak_self = self;

self.pan(pan,_itemStyle,weak_self);

}

}

@end

@interface OYRSlider ()

{

//data

NSMutableArray * _titleLabelArray;

NSMutableArray * _buttomLineArray;

int _mixValue;

int _maxValue;

//View

//    IFRangeSliderItem * _leftItem;

//    IFRangeSliderItem * _rightItem;

UIImageView * _bottomView;

UIImageView * _upView;

}

//@property(nonatomic,strong)IFRangeSliderItem * leftItem;

//@property(nonatomic,strong)IFRangeSliderItem * rightItem;

@property(nonatomic,strong)UIImageView * upView;

@end

@implementation OYRSlider

@synthesize rightItem = _rightItem;

@synthesize upView = _upView;

-(void)dealloc

{

dealocInfo;

}

#pragma mark

#pragma mark          porperty

#pragma mark

-(void)setTitleHeight:(CGFloat )titleHeight

{

_titleHeight = titleHeight;

[self refreshView];

}

-(void)setTitleArray:(NSArray *)titleArray

{

_titleArray = titleArray;

if(_maxValue == 0)

_maxValue = 1;//(int)titleArray.count - 1;

[self refreshView];

}

-(void)setTitleColor:(UIColor *)titleColor

{

_titleColor = titleColor;

[self refreshView];

}

-(void)setTitleFont:(UIFont *)titleFont

{

_titleFont = titleFont;

[self refreshView];

}

//滑块

-(void)setBottomColor:(UIColor *)bottomColor

{

_bottomColor = bottomColor;

[self refreshView];

}

-(void)setUpColor:(UIColor *)upColor

{

_upColor = upColor;

[self refreshView];

}

-(void)setSliderItemSize:(CGFloat)sliderItemSize

{

_sliderItemSize = sliderItemSize;

[self refreshView];

}

-(void)setBottomViewHeight:(CGFloat)bottomViewHeight

{

_bottomViewHeight = bottomViewHeight;

[self refreshView];

}

-(void)setUpViewHeight:(CGFloat)upViewHeight

{

_upViewHeight = upViewHeight;

[self refreshView];

}

#pragma mark

#pragma mark          init view

#pragma mark

- (id)initWithFrame:(CGRect)frame

{

self = [super initWithFrame:frame];

if (self) {

// Initialization code

self.userInteractionEnabled = YES;

//init data

_titleLabelArray = [[NSMutableArray alloc] initWithCapacity:0];

_buttomLineArray = [[NSMutableArray alloc] initWithCapacity:0];

//init config 设置默认的

_titleHeight = 0;

_titleColor = [UIColor colorWithRed:153/255.0 green:153/255.0 blue:153/255.0 alpha:1];//[UIColor grayColor];

_titleFont = [UIFont systemFontOfSize:10.0f];

_titleSelectColor = [UIColor colorWithRed:0/255.0 green:143/255.0 blue:226/255.0 alpha:1];

_upViewHeight = 5;

_bottomViewHeight = 5;

_bottomColor = [UIColor colorWithRed:174/255.0 green:195/255.0 blue:208/255.0 alpha:1];//[UIColor colorWithWhite:0.788 alpha:1.000];

_upColor = [UIColor colorWithRed:0/255.0 green:143/255.0 blue:226/255.0 alpha:1];//baseColor;

_sliderItemSize = 20;

_maxValue = 0;

_mixValue = 0;

[self refreshView];

}

return self;

}

#pragma mark

#pragma mark          help

#pragma mark

-(void)refreshView

{

//清空之前的title

while (_titleLabelArray.count > 0)

{

[_titleLabelArray.lastObject removeFromSuperview];

[_titleLabelArray removeLastObject];

}

//重新加载新标题

CGFloat width = _titleArray == nil ? 0 : self.frame.size.width/_titleArray.count;//标题长度

for (int i = 0; i < _titleArray.count; i++)

{

UILabel * titleLabel = [[UILabel alloc] initWithFrame:(CGRect){{i*width,0},{width,_titleHeight}}];

titleLabel.textColor = _titleColor;

titleLabel.font = _titleFont;

titleLabel.tag = i;

titleLabel.textAlignment = NSTextAlignmentCenter;

if (0 == i)

{

titleLabel.textAlignment = NSTextAlignmentLeft;

}else if (_titleArray.count - 1 == i)

{

titleLabel.textAlignment = NSTextAlignmentRight;

}

if (i == _maxValue) {

titleLabel.textColor =  _titleSelectColor;

}else{

titleLabel.textColor = _titleColor;

}

[self addSubview:titleLabel];

titleLabel.text = [_titleArray objectAtIndex:i];

[_titleLabelArray addObject:titleLabel];

}

//加载滑块

//加底部线

[_bottomView removeFromSuperview];

if (_bottomView == nil)

{

_bottomView = [[UIImageView alloc] init];

}

_bottomView.frame = CGRectMake(0,_titleHeight + 10 + _sliderItemSize/2 - _bottomViewHeight/2, self.frame.size.width, _bottomViewHeight);

_bottomView.layer.cornerRadius = _bottomViewHeight/2;

_bottomView.backgroundColor = _bottomColor;

[self addSubview:_bottomView];

//加上分割线

while (_buttomLineArray.count > 0)

{

[_buttomLineArray.lastObject removeFromSuperview];

[_buttomLineArray removeLastObject];

}

for (NSInteger i = 1; i < 8; i ++) {

UILabel * line = [[UILabel alloc]initWithFrame:CGRectMake(i * width + width/2,0, 1, _bottomView.frame.size.height)];

line.backgroundColor = [UIColor colorWithRed:153/255.0 green:153/255.0 blue:153/255.0 alpha:1];

[_buttomLineArray addObject:line];

[_bottomView addSubview:line];

}

//加上部线

[_upView removeFromSuperview];

if (_upView == nil)

{

_upView = [[UIImageView alloc] init];

}

CGFloat mixX = 0;//_mixValue == 0 ? _sliderItemSize/2 :(_mixValue*width + width/2);

CGFloat maxX = _maxValue == 0 || _maxValue == _titleArray.count - 1 ? (self.frame.size.width - _sliderItemSize/2) : _maxValue*width + width/2;

_upView.frame = CGRectMake(mixX,_titleHeight + 10 + _sliderItemSize/2 - _upViewHeight/2,maxX - mixX, _upViewHeight);

_upView.backgroundColor = _upColor;

_upView.layer.cornerRadius = _bottomViewHeight/2;

[self addSubview:_upView];

//加滑块

[_rightItem removeFromSuperview];

if (_rightItem == nil)

{

_rightItem = [[OYRSliderItem alloc] init];

}

_rightItem.frame = CGRectMake(0, 0, _sliderItemSize + 5, _sliderItemSize + 5);

//_rightItem.layer.cornerRadius = _sliderItemSize/2;

//[_rightItem.layer masksToBounds];

_rightItem.backgroundColor = [UIColor clearColor];//_upColor;

_rightItem.itemStyle = 1;

_rightItem.range = 1;//(int)_titleArray.count - 1;

_rightItem.center = CGPointMake(maxX, _upView.center.y);

[self addSubview:_rightItem];//最大值的滑块

//滑块的滑动block

typeof(self)__weak weak_self = self;

void (^pan)(UIPanGestureRecognizer * pan,int itemStyle ,OYRSliderItem * item) = ^(UIPanGestureRecognizer * pan,int itemStyle,OYRSliderItem * item)

{

typeof(weak_self) __strong strong_self = weak_self;

if (strong_self)

{

if (pan.state == UIGestureRecognizerStateBegan)

{

NSLog(@"UIGestureRecognizerStateBegan");

}

if (pan.state == UIGestureRecognizerStateChanged)

{

NSLog(@"UIGestureRecognizerStateChanged");

CGPoint point = [pan locationInView:strong_self];

CGFloat x = point.x;//获取滑块的起始坐标

if (1 == itemStyle)//右滑块

{

if (x > (strong_self.frame.size.width - strong_self.sliderItemSize/2))

{

x = strong_self.frame.size.width - strong_self.sliderItemSize/2 + 2;

}

if(x < strong_self.sliderItemSize/2)

{

x = strong_self.sliderItemSize/2;

}

item.center = CGPointMake(x, item.center.y);

}

//跳整上面的浮动宽度

CGFloat width = self.rightItem.center.x - 0;

strong_self.upView.frame = CGRectMake(0, strong_self.upView.frame.origin.y,width,strong_self.upViewHeight);//调整选中的坐标

}

if (pan.state == UIGestureRecognizerStateEnded)

{

NSLog(@"UIGestureRecognizerStateEnded");

[strong_self adjustSliderItem];

}

}

};

//设置block

_rightItem.pan = pan;

}

//调整滑块到正确的结点

-(void)adjustSliderItem

{

CGFloat width = _titleArray == nil ? 0 : self.frame.size.width/_titleArray.count;//一个刻度的宽

CGPoint center;

//右边

int range = _rightItem.center.x/width;//右边滑到的位置

NSLog(@"  range 1 :%d",range);

if (range == _titleArray.count - 1)

{

if (_rightItem.center.x < self.frame.size.width - width/2)

{

range --;

center =  CGPointMake(range * width + width/2, _rightItem.center.y);

}else{

center =  CGPointMake((range + 1) * width - self.sliderItemSize/2 + 2, _rightItem.center.y);

}

}else if(range == 0){

center =  CGPointMake(self.sliderItemSize/2 - 2, _rightItem.center.y);

}else{

center =  CGPointMake(range * width + width/2, _rightItem.center.y);

}

NSLog(@"  range 2 :%d",range);

//__weak __typeof(&*self)weakSelf = self;

[UIView animateWithDuration:0.2 animations:^{

_rightItem.center = center;

_upView.frame = CGRectMake(_upView.frame.origin.x, _upView.frame.origin.y, _rightItem.center.x, _upView.frame.size.height);

} completion:^(BOOL finished){

_rightItem.range = range;

_maxValue = range;

//改变title的颜色

for (UILabel * lab in _titleLabelArray) {

if (lab.tag == _maxValue) {

lab.textColor = _titleSelectColor;

}else{

lab.textColor = _titleColor;

}

}

//此处加值变化通知

[self sendActionsForControlEvents:UIControlEventValueChanged];

}];

}

/*

// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect {

// Drawing code

}

*/

@end

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341

推荐阅读更多精彩内容