【仿汽車之家】價格區間選擇控制元件
為了響應使用者的拖動手勢,給兩個把手(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;
在viewDidLoad中初始化
- (void)viewDidLoad {
[super viewDidLoad];
leftValue = 0;
rightValue = 100;
[self setUpView];
}
然後在leftHandMove:和rightHandMove:中將使用者選中的值分別賦值給leftValue和rightValue。
<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;
}
執行程式,現在已經不能將右把手拖動到左把手的前面的吧~