1. 程式人生 > >【仿汽車之家】價格區間選擇控制元件

【仿汽車之家】價格區間選擇控制元件

為了響應使用者的拖動手勢,給兩個把手(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;
}

執行程式,現在已經不能將右把手拖動到左把手的前面的吧~