7

ユーザーが距離を設定するために操作できるUISliderを実装しています。私はCocoaTouchUISliderを使用したことはありませんが、他のフレームワークスライダーを使用しました。通常、「ステップ」および他の「ヘルパー」プロパティを設定するための変数があります。

UISliderのドキュメントでは、最大値と最小値のみを扱っており、出力は常に「スライダーノブ」の位置と線形関係にある小数点以下6桁の浮動小数点数です。必要な機能を段階的に実装する必要があると思います。

ユーザーにとって、最小/最大値の範囲は10mから999Kmです。これを指数関数的に実装しようとしています。これは、ユーザーにとって自然な感じです。つまり、ユーザーは、大小を問わず、値を制御できるという感覚を体験します。また、「出力」には妥当な値があります。1.2342356mまたは108.93837756kmの代わりに、10m 200m 2.5km150kmなどの値。

最初の200mでステップサイズを10m増やし、次に50mから500mまで増やして、1000 mの値を超えると、キロメートルを処理し始めるので、ステップサイズ=1kmまでです。 50 km、それからおそらく25kmのステップなど。

いずれにせよ、ユーザーがスライダーを少し動かすたびに、多くの丸めと多くの計算をifステートメントとNSString/Number変換のフォレストにラップして実行することになります。

私は誰かが私に少しのインスピレーション/数学の助けを貸してくれるか、この問題を解決するためのより無駄のないアプローチを私に気づかせてくれることを望んでいました。

私の最後のアイデアは、100個の文字列値を入力して配列し、スライダーのint値を文字列に対応させることです。これはあまり柔軟ではありませんが、実行可能です。

助けてくれてありがとう:)

4

6 に答える 6

5

クイックスケーリングソリューションには、次の3つの特別な方法があります。

- (CGFloat)scaleValue:(CGFloat)value {
    return pow(value, 10);
}

- (CGFloat)unscaleValue:(CGFloat)value {
    return pow(value, 1.0 / 10.0);
}

- (CGFloat)roundValue:(CGFloat)value {
    if(value <=   200) return floor(value /   10) * 10;
    if(value <=   500) return floor(value /   50) * 50;
    if(value <=  1000) return floor(value /  100) * 100;
    if(value <= 50000) return floor(value / 1000) * 1000;
    return floor(value / 25000) * 25000;
}

スライダーの変更に反応すると、次のようになります。

- (void)sliderChange:(id)sender {
    CGFloat value = mySlider.value;
    value = [self scaleValue:value];
    value = [self roundValue:value];
    valueLabel.text = [NSString stringWithFormat:@"%f", value];
}

次のコードで初期化できます。

mySlider.maximumValue = [self unscaleValue:999000];
mySlider.minimumValue = [self unscaleValue:10];

上記のすべてを問題なく動作させることができましたが、防弾を使用することができました。scaleValue:andメソッドはサポートされていない値をチェックする必要があり、メソッドの方が効率的であるとunscaleValue:確信しています。sliderChange:

速度の点では、これは配列からオブジェクトを引き出すよりも速いと確信しています。実際のスライダーの動作は少し不安定に感じるかもしれませんし、スライダーで利用できる値を正確に制御できないため、希望どおりに動作しない可能性があります。本当に高いパワーを使うことはそれをより便利にするように思われました。

于 2010-05-12T21:02:25.827 に答える
2

「ステップサイズ」を設定して、次のようにスライダーを作成することもできます。

- (void) sliderChanged:(UISlider *)slider
{
    int value = (int)[slider value];
    int stepSize = 500.0f;

    value = value - value%stepSize;

    [km setText:[NSString stringWithFormat:@"%d Km",value]];
}

このソリューションと一緒に、2つのボタン(+と-)を配置してスライダーの値を調整できます。

- (void) incrementKm:(UIButton *)button 
{
    [kmSlider setValue:[kmSlider value] + 500.0f animated:YES];
    [self sliderChanged:kmSlider]; 
}

- (void) decrementKm:(UIButton *)button 
{
    [kmSlider setValue:[kmSlider value] - 500.0f animated:YES];
    [self sliderChanged:kmSlider]; 
}
于 2011-07-27T16:39:11.313 に答える
1

スライダーに選択させたいオプションの可変長配列がある場合のオプションは次のとおりです。

-(void)setupSlider {

    //this has to be (scale - 1) from sliderChanged selector to avoid index out of bounds error
    _sldOptionPicker.maximumValue = 99;  

    //should be zero
    _sldOptionPicker.minimumValue = 0;

    //can be any value 0 to 99
    _sldOptionPicker.value = 0;        

}

-(IBAction)sliderChanged:(id)sender {

    float scale = 100 / [optionsArray count];

    int index = (int)(_sldOptionPicker.value / scale);

    Option *mySelectedOption = (Option*)[optionsArray objectForIndex:index];

}
于 2012-03-07T14:33:03.173 に答える
0

最も簡単な答えは、さまざまな「ステップサイズ」でセグメント化されたコントロールを使用することです。ユーザーが選択するオプションに応じて、スライダーのステップサイズが決まります。私はこれがおそらくそれにアプローチするためのよりユーザーフレンドリーな方法であることをお勧めします:)。

Dappを使用してアプリの外観を自由に試して、セグメント化されたコントロールがデザインにどのように適合するかを確認してください。

しかし...あなたはよりスリムなアプローチを望んでいました;)。

必要な10ほどのステップを書き始めましたが、おそらくすでに同様の解決策に到達していることに気付いたときに停止しました。文字列配列のアイデアは問題ありません。スライダーの値を整数に変換し、配列から関連するインデックスを取得するだけだと思いますか?

プログラマーとして、問題へのアプローチに行き過ぎてしまうことがあります。はい、文字列配列は最も「柔軟な」ソリューションではありませんが、高速です。そして、私は、天才的な数学的解決策でさえ、あなたが思うほど柔軟ではないと主張したいと思います。また、値をすぐに変更する予定がなく、スライダーごとにスライダーの範囲を変える必要がない場合は、静的配列を作成するだけで十分です。

幸運を!:)

于 2010-05-11T18:47:54.543 に答える
0
+ (NSArray*) getSliderNumbers {

    NSArray *sliderNumbers = [NSArray arrayWithObjects:@"10",
                          @"20",
                          @"30",
                          @"40",
                          @"50",
                          @"60",
                          @"70",
                          @"80",
                          @"90",
                          @"100",
                          @"150",
                          @"200",
                          @"250",
                          @"300",
                          @"350",
                          @"400",
                          @"450",
                          @"500",
                          @"600",
                          @"700",
                          @"800",
                          @"900",
                          @"1",
                          @"1.5",
                          @"2.0",
                          @"2.5",
                          @"3.0",
                          @"3.5",
                          @"4",
                          @"4.5",
                          @"5",
                          @"5.5",
                          @"6",
                          @"6.5",
                          @"7",
                          @"7.5",
                          @"8",
                          @"8.5",
                          @"9",
                          @"9.5",
                          @"10",
                          @"15",
                          @"20",
                          @"25",
                          @"30",
                          @"35",
                          @"40",
                          @"45",
                          @"50",
                          @"55",
                          @"60",
                          @"65",
                          @"70",
                          @"75",
                          @"80",
                          @"85",
                          @"90",
                          @"95",
                          @"100",
                          @"200",
                          @"300",
                          @"400",
                          @"500",
                          @"600",
                          @"700",
                          @"800",
                          @"900",
                          nil];
    return sliderNumbers;

}

上記はインスタンス化時に配列にロードされます:

スライダーを設定します。

    customSlider.minimumValue = 0.0f;
    customSlider.maximumValue = (CGFloat)[sliderNumbers count] - 1;
    customSlider.continuous = YES;
    customSlider.value = customSlider.maximumValue;

呼び出されたメソッドUIControlEventValueChanged

- (void) sliderMove:(UISlider*) theSlider {

    NSInteger numberLookup = lroundf([theSlider value]);

    NSString *distanceString = [sliderNumbers objectAtIndex:numberLookup];
    CGFloat distanceInMeters;

    if (numberLookup > 21) {

        [self.indicator.indicatorLabel setText:[NSString stringWithFormat:@"%@ km", distanceString]];       
        distanceInMeters = [distanceString floatValue] * 1000;
    } else {

        [self.indicator.indicatorLabel setText:[NSString stringWithFormat:@"%@ m", distanceString]];
        distanceInMeters = [distanceString floatValue];
    }

    if (oldDistanceInMeters != distanceInMeters) {

        [self.delegate distanceSliderChanged:distanceInMeters];
        oldDistanceInMeters = distanceInMeters;
    }
}

これにより、ユーザーインターフェイスの文字列(「200m」や「1.5km」など)のフォーマットも処理され、述語で結果を並べ替えるときに使用する距離番号(メートル)でデリゲートが更新されます。

于 2010-05-14T12:33:18.763 に答える
0

これを正しく行うには、スライダーで指数を表す必要があります。したがって、たとえば10-100000のスケールが必要な場合は、スライダーの範囲を1(10 = 10 ^ 1)から5(100,000 = 10 ^ 5)にする必要があります。スライダーのステップを分数に設定して、必要な精度を得ることができます。私の例では、出力に最小20,000、最大20,000,000を使用します(これを理解するために座ったときに必要だったため)。基本的に最小から最大まで1000倍に増加するので、10 ^ 3が必要なので、スライダーは0〜3になります(10 ^ 0は1に評価されます)。.001ステッピングを使用するので、合計3000の可能な位置があります。これを実現するために必要なコードは次のとおりです。

  $("#amount-slider").slider({
   value:20000,
   min: 0,
   max: 3,
   step:.001,
   slide: function(event, ui) {
    $("#amount").val(Math.pow(10, ui.value)*20000);
   }
  });

この関数の逆が必要な場合は、外部入力を指定してスライダーの位置を設定できます。次に、対数を使用します。

  var amtVal = parseFloat($("#amount").val());

  $('#amount-slider').slider('value', ((Math.log(amtVal/20000)/Math.log(10))));

基本量に一致するように、両方の関数で20000を調整する必要があります。最大値を10以外の指数で導出する必要がある場合は、最大値(指数)だけでなく10も変更します。10の累乗で上がると、生活が楽になります。

于 2010-07-21T23:20:04.857 に答える