首页 文章

如何使UISlider输出以指数方式呈现精美的舍入数字?

提问于
浏览
7

我正在实现一个用户可以操作设置距离的UISlider . 我从未使用过CocoaTouch UISlider,但是使用过其他框架滑块,通常有一个变量用于设置“step”和其他“helper”属性 .

UISlider的文档仅处理最大值和最小值,输出始终为6十进制浮点数,与“滑块nob”的位置成线性关系 . 我想我将不得不一步一步地实现所需的功能 .

对于用户来说,最小/最大值的范围从10米到999公里,我试图以指数方式实现这一点,这对用户来说是自然的 . 即用户体验到对 Value 的控制感,无论大小 . 此外,“输出”具有合理的 Value . 值如10m 200m 2.5km 150 km等而不是1.2342356 m或108.93837756 km .

我希望步长增加10米,前200米,然后可能是50米到500米,然后当通过1000米时,它开始处理公里,所以它的步长= 1公里直到50公里,然后可能25公里步等 .

无论如何,我最终会进行大量的舍入和大量的计算,包含在for语句和NSString / Number转换中,每次用户移动滑块一点点 .

我希望有人能借给我一些灵感/数学帮助,或者让我意识到一种更精益的方法来解决这个问题 .

我的最后一个想法是用100个字符串值填充和数组,然后让滑块int值对应一个字符串,这不是很灵活,但可行 .

提前感谢您给予的任何帮助:)

6 回答

  • 1

    最简单的答案是使用具有不同“步长”的分段控件 . 根据用户选择的选项,滑块将具有哪个步长 . 我甚至建议这可能是一个更友好的方式来接近它:) .

    随意使用Dapp来玩你的应用程序的外观,看看分段控件如何适合设计 .

    但是......你想要更精简的方法;) .

    我开始编写所需的10个左右的步骤,但当我意识到你可能已经找到类似的解决方案时,我停了下来 . 您的字符串数组的想法很好,我假设您只需将滑块值转换为整数并从数组中获取相关索引?

    有时作为程序员,我们对问题的解决方法走得太远了 . 是的,字符串数组不是最“灵活”的解决方案,但速度很快!而且,我认为即使是天才的数学解决方案也不像你想象的那么灵活 . 此外,如果您不打算很快改变值,并且不需要在不同的滑块上使用不同的滑块范围,那么创建一个静态数组是有意义的 .

    祝好运! :)

  • 0

    快速扩展解决方案涉及三种特殊方法:

    - (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:unscaleValue: 方法应检查不支持的值,我确信 sliderChange: 方法可能更有效 .

    就速度而言,我确信这比从数组中提取对象更快 . 实际的滑块行为可能会感觉有点不稳定,并且没有太多控制滑块可用的确切值,因此可能无法完全按照您的要求进行操作 . 使用真正的高权力似乎使它更有用 .

  • 0

    您还可以设置“步长”来构建滑块,如下所示:

    - (void) sliderChanged:(UISlider *)slider
    {
        int value = (int)[slider value];
        int stepSize = 500.0f;
    
        value = value - value%stepSize;
    
        [km setText:[NSString stringWithFormat:@"%d Km",value]];
    }
    

    与此解决方案一起,您可以放置两个按钮(和 - )来调整滑块值:

    - (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]; 
    }
    
  • 5

    如果您希望滑块选择可变长度的选项数组,则可以选择以下选项:

    -(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];
    
    }
    
  • 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;
        }
    }
    

    这甚至负责格式化用户界面的字符串,例如“200米”或“1.5公里”并使用距离数字以米为单位更新代表,以便在使用谓词对结果进行排序时使用 .

  • 2

    为了做到这一点,您希望滑块代表指数 . 因此,例如,如果您想要10-100000的比例,您希望滑块的范围为1(10 = 10 ^ 1)到5(100,000 = 10 ^ 5) . 您可以将滑块上的步进设置为a分数,以便为您提供所需的精度 . 对于我的例子,我将使用最小20,000和最大20,000,000的输出(因为这是我在坐下来想出这个时所需要的) . 因为我基本上要从min到max增加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以匹配您的基本金额 . 如果你的max必须通过10以外的指数得出,则改变10以及max(指数) . 如果你以十的力量上升,生活会更容易 .

相关问题