如何使UISlider输出呈指数级的圆形数字?

Ric*_*kiG 7 iphone uislider

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

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

对于用户来说,最小/最大值的范围从10米到999公里,我试图以指数方式实现这一点,这对用户来说是自然的.即,用户体验到对价值的控制感,无论大小.此外,"输出"具有合理的价值.值如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值对应一个字符串,这不是很灵活,但可行.

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

MrH*_*Hen 5

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

- (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;
}
Run Code Online (Sandbox Code Playgroud)

对滑块更改的反应类似于:

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

您可以使用以下代码初始化:

mySlider.maximumValue = [self unscaleValue:999000];
mySlider.minimumValue = [self unscaleValue:10];
Run Code Online (Sandbox Code Playgroud)

我完成了以上所有工作,没有任何问题,但它可以使用一些防弹.该scaleValue:unscaleValue:方法应检查是否有不支持的价值观,我相信sliderChange:方法可能变得更高效.

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


Cli*_*gas 0

最简单的答案是使用具有不同“步长”的分段控件。根据用户选择的选项,滑块的步长是多少。我什至建议这可能是一种更用户友好的方法:)。

请随意使用Dapp来调整应用程序的外观,看看分段控件如何适合设计。

然而...您想要一种更精简的方法;)。

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

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

祝你好运!:)