【仿汽车之家】价格区间选择控件
来源:互联网 发布:Linux指令批量执行 编辑:程序博客网 时间:2024/04/26 07:50
仿照汽车之家iOS客户端“找车”栏目的价格区间选择控件,最终实现效果如下:
一、界面实现
*根据屏幕大小以及刻度的大小,宏定义需要用到的一些值
#define SCREENW [UIScreen mainScreen].bounds.size.width#define SCREENH [UIScreen mainScreen].bounds.size.height#define PRICEBGW 271.0#define PRICEBGH 21.0#define PRICEBGX (SCREENW - PRICEBGW)*0.5#define PRICEBGY (SCREENH - PRICEBGH)*0.5#define PRICEMAX (SCREENW*0.5 + PRICEBGW*0.44)#define PRICEMIN (SCREENW*0.5 - PRICEBGW*0.45)#define NODE1 (PRICEBGX + 103)
项目中用了两张图片,一张是刻度图(紫色框中的UIIMageView,图片命名为priceRuler@2x.png),一张是把手图(两个红色框内分别有一个UIIMageView,图片命名为xiabashou@2x.png),蓝色框内的进度条,使用一个UIView来实现,而使用UILabel来显示用户选择的数值范围。
priceRuler@2x.png
xiabashou@2x.png
我们把界面实现的代码写到一个函数中,函数名为setUpView,并在viewDidLoad中调用。
-(void)setUpView{ //数值显示 resultLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, SCREENW, 60)]; [resultLabel setTextAlignment:NSTextAlignmentCenter]; [resultLabel setFont:[UIFont systemFontOfSize:18]]; [self.view addSubview:resultLabel]; //刻度图 UIImageView *priceBg = [[UIImageView alloc] initWithFrame:CGRectMake(PRICEBGX, PRICEBGY, PRICEBGW, PRICEBGH)]; [priceBg setImage:[UIImage imageNamed:@"priceBg"]]; [self.view addSubview:priceBg]; //蓝色进度条 progressView = [[UIView alloc] initWithFrame:CGRectMake(PRICEBGX, CGRectGetMaxY(priceBg.frame)-2, PRICEBGW, 2.f)]; [progressView setBackgroundColor:[UIColor colorWithRed:30.0/255.0 green:144.0/255.0 blue:255.0/255.0 alpha:1.0]]; [self.view addSubview:progressView]; //左把手 CGFloat commonHandImageViewW = 20.f; CGFloat commonHandImageViewH = 25.f; CGFloat leftHandImageViewX = PRICEBGX - commonHandImageViewW*0.5; CGFloat leftHandImageViewY = PRICEBGY + commonHandImageViewH; leftHandImageView = [[UIImageView alloc] initWithFrame:CGRectMake(leftHandImageViewX, leftHandImageViewY, commonHandImageViewW, commonHandImageViewH)]; [leftHandImageView setImage:[UIImage imageNamed:@"xiabashou"]]; [self.view addSubview:leftHandImageView]; //右把手 CGFloat rightHandImageViewX = CGRectGetMaxX(priceBg.frame) - commonHandImageViewW*0.5; CGFloat rightHandImageViewY = leftHandImageViewY; rightHandImageView = [[UIImageView alloc] initWithFrame:CGRectMake(rightHandImageViewX, rightHandImageViewY, commonHandImageViewW, commonHandImageViewH)]; [rightHandImageView setImage:[UIImage imageNamed:@"xiabashou"]]; [self.view addSubview:rightHandImageView];}
现在运行项目,已经可以看到一个区间选择器了,但是我们在屏幕进行任意拖动操作,界面并没有任何改变。因此我们需要使得app能够响应我们的手势。
二、响应用户手势
为了响应用户的拖动手势,给两个把手(UIIMageView)分别添加滑动手势识别(UIPanGestureRecognizer)。我们在setUpView中继续添加如下代码
-(void)setUpView{ ….…. //给左把手添加滑动手势识别 UIPanGestureRecognizer *leftPanRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(leftHandMove:)]; [leftPanRecognizer setMinimumNumberOfTouches:1]; [leftPanRecognizer setMaximumNumberOfTouches:1]; [leftHandImageView setUserInteractionEnabled:YES]; [leftHandImageView addGestureRecognizer:leftPanRecognizer]; //给右把手添加滑动手势识别 UIPanGestureRecognizer *rightPanRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(rightHandMove:)]; [rightHandImageView setUserInteractionEnabled:YES]; [rightHandImageView addGestureRecognizer:rightPanRecognizer]; }
实现leftHandMove:和rightHandMove:方法,处理滑动事件:
-(void)leftHandMove:(UIPanGestureRecognizer *)pan{ CGPoint point = [pan translationInView:leftHandImageView]; CGFloat x = leftHandImageView.center.x + point.x; if(x > PRICEMAX){ x = PRICEMAX; }else if (x< PRICEBGX ){ x = PRICEBGX; } leftHandImageView.center = CGPointMake(ceilf(x), leftHandImageView.center.y); [pan setTranslation:CGPointZero inView:self.view];}
-(void)rightHandMove:(UIPanGestureRecognizer *)pan{ CGPoint point = [pan translationInView:rightHandImageView]; CGFloat x = rightHandImageView.center.x + point.x; if(x>PRICEBGX+PRICEBGW){ x = PRICEBGX+PRICEBGW; }else if (x<PRICEMIN){ x = PRICEMIN; } rightHandImageView.center = CGPointMake(ceilf(x), rightHandImageView.center.y); }
在leftHandMove:方法中,我们使用translationInView函数,得到在指定的View坐标系中的改变值point,将原来的x坐标值加上改变的值后,若超出符合要求的刻度范围,我们要设置其为边界值,然后再更新把手的位置,否则直接更新即可。rightHandMove:同理实现。
尝试运行项目并拖动把手,现在把手的位置可以水平拖动了,但是UILabel还没有显示我们选中的范围,蓝色进度条也没随之改变。
三、更新数值显示和蓝色进度条
为了得到上一步中用户选中的值,我们先声明两个个全局变量:
float leftValue;float rightValue;
- (void)viewDidLoad { [super viewDidLoad]; leftValue = 0; rightValue = 100; [self setUpView];}
<pre code_snippet_id="1582410" snippet_file_name="blog_20160219_8_6433823" name="code" class="objc">-(void)leftHandMove:(UIPanGestureRecognizer *)pan{……leftValue = x;
</pre><pre code_snippet_id="1582410" snippet_file_name="blog_20160219_9_4132529" name="code" class="objc">}
现在,我们写一个更新数值和进度条的函数,函数名为updateData。
-(void)updateData{ [resultLabel setText:[NSString stringWithFormat:@"%.0f~%.0f",leftValue,rightValue]];}
我们再一次运行程序,滑动手柄,数值虽然改变了,但并不是我们想要的价格数值!!
这是因为屏幕的坐标和刻度图的坐标范围并不一致,因此我们需要将数据处理一下。可能你已经发现,刻度图中的范围并不是均匀分布的,而是分成三段:0~25、25~40、40~100。因此我们在处理时需要分段处理。
我们写一个将左边转换为价格的转换函数:
//坐标->价格-(CGFloat)x2price:(CGFloat)x{ CGFloat price = 0.f; //<5 if(x < PRICEMIN){ price = 0; } //5~25 else if (x < PRICEBGX + 133){ price = (x - PRICEMIN) / 120 * 20 + 5; } //25~40 else if (x < PRICEBGX + 163){ price = (x - PRICEBGX - 133) *0.5 + 25; } //40~100 else if (x < PRICEBGX + 253){ price = (x - PRICEBGX - 163) * 2 / 3 + 40; } //100+ else{ price = 100; } return price;}
将leftHandMove:中的leftValue = x;修改为如下
-(void)leftHandMove:(UIPanGestureRecognizer *)pan{ …… leftValue = [self x2price:ceilf(x)];}
同理rightHandMove:也做相应处理。重新运行程序,滑动把手,显示的价格数值正是我们所期望的。
我们还要更新蓝色进度条,只需修改它的frame即可:
-(void)updateData{ [resultLabel setText:[NSString stringWithFormat:@"%.0f~%.0f",leftValue,rightValue]]; CGRect progressRect = CGRectMake(leftHandImageView.center.x, progressView.frame.origin.y, rightHandImageView.center.x - leftHandImageView.center.x, progressView.frame.size.height); progressView.frame = progressRect;}
四、优化
当将右边的把手一直往左滑动,它将滑到左边把手的左边,也就是用户选择的区间中,上界值比下界值更小了!这并不是我们期望的结果。我们希望上界至少要比下界大1个单位,所以当用户滑动右把手到上界比下界小于等于1时,左把手也要跟着滑动,与右把手始终保持1个单位。
我们在rightHandMove:函数中添加如下代码:
-(void)rightHandMove:(UIPanGestureRecognizer *)pan{ …… if (rightValue-leftValue <= 1) { leftValue = rightValue - 1; leftHandImageView.center = CGPointMake([self price2x:leftValue], leftHandImageView.center.y); }}
同理在leftHandMove:函数中添加对应代码:
-(void)leftHandMove:(UIPanGestureRecognizer *)pan{ …… if (rightValue-leftValue <= 1) { rightValue = leftValue + 1; rightHandImageView.center = CGPointMake([self price2x:rightValue], rightHandImageView.center.y); } }
注意到函数中用到了方法price2x:,这个函数是将价格转换为对应的x坐标,作用于前面用到的x2price:刚好相反。
//价格->坐标-(CGFloat)price2x:(CGFloat)price{ CGFloat x; //<5 if (price<5) { x = PRICEBGX; } //5~25 else if (price >= 5 && price < 25) { x = (price-5) * 6 + PRICEMIN; } //25~40 else if (price >= 25 && price <40) { x = (price-25) * 2 + 133 + PRICEBGX; } //40~100 else if (price >=40 && price <100){ x = (price-40) * 3/2 +163 + PRICEBGX; }else if(price >= 100){ x = PRICEBGX + PRICEBGW; } return x;}
运行程序,现在已经不能将右把手拖动到左把手的前面的吧~
完整源代码下载:http://download.csdn.net/detail/dolacmeng/9436673
- 【仿汽车之家】价格区间选择控件
- Android自定义控件之仿汽车之家下拉刷新
- Android自定义控件之仿汽车之家下拉刷新
- 汽车价格会走入下跌区间
- 价格区间选择案例 吸附功能
- 类似淘宝的选择价格区间Demo
- ecshop价格范围区间用户自定义选择价格代码
- 仿ios日期选择控件
- 仿ios开关选择控件
- 实现滑动选择价格区间的自定义seekbar
- 【无限互联】学员作品:仿汽车之家的App
- 汽车之家招聘
- 汽车之家面试:
- 汽车之家 报价
- android 自定义控件之汽车仪表盘
- android 仿IOS的滚轮选择控件
- 【Qt】仿QQ表情选择控件
- 仿IOS7日期选择控件(新)
- iOS上传语音到服务器
- 【Android学习笔记】判断字符串的字符数
- php.h No such file or directory
- Android 开源项目分类汇总
- 面试6 -- JAVA中常见的几种RuntimeException
- 【仿汽车之家】价格区间选择控件
- 硬件极客最爱:支持WiFi的Arduino板来了
- poj2342树形dp
- 用android控制arduino(wifi版)
- Oracle、Mysql、SQLServer数据分页查询
- Database LeetCode Second Highest Salary
- 日本猥琐雨伞设计:裙底伞
- ML学习分享系列(2)_计算广告小窥[中]
- android:自定义HorizontalScrollView实现qq侧滑菜单 标签: HorizontalScrollView自定义viewqq侧滑菜单 2016