3 взаимосвязанных ползунка - PullRequest
4 голосов
/ 22 декабря 2010

Я два дня ломал голову над этой проблемой, пробовал разные вещи, но ни одна из них не работает.Я создаю приложение, которое является своего рода викториной.Есть три предмета, которые содержат вопросы.Я хотел бы использовать 3 ползунка, чтобы определить процент вопросов, которые им нужны по каждому предмету.

ex : slider one   = History
     slider two   = Maths
     slider three = Grammar

Если я выберу больше истории, я сдвигаю ползунок истории вверх, а остальные ползунки должны уменьшаться в соответствиизначения, которые они должны достичь 100% для 3 ползунков ...

Есть идеи для алгоритма?И что происходит, когда один слайдер достигает нулевого значения?

Математика никогда не была моей сценой.

Любая помощь будет очень цениться.

Заранее спасибо.

Майк

Ответы [ 3 ]

6 голосов
/ 22 декабря 2010

Хотя ответ Snowangelic хорош, я думаю, что имеет смысл ограничить соотношение между неизмененными значениями следующим образом.

Пусть s1, s2, s3 - текущие значения ползунков, так что s1+ s2 + s3 = 100.Вы хотите найти для n1, n2, n3 новые значения ползунков, так что n1 + n2 + n3 = 100.Предположим, s1 изменен на n1 пользователем.Затем это добавляет следующее ограничение:

n2 / n3 = s2 / s3

Таким образом, решение проблемы при n1 + n2 + n3 = 100 будет

n2= (100-n1) / (s3 / s2 + 1) или 0 (если s2 = 0) и

n3 = (100-n1) / (s2 / s3 + 1) или 0 (если s3 =0)

1 голос
/ 22 декабря 2010

Начните все три ползунка с 33,333 ...%

Когда пользователь перемещает ползунок вверх, скажем, на 10%: сдвиньте два других ползунка вниз на 5%.Но если один из двух ползунков достигает 0 =>, переместите другой только на десять процентов.Таким образом, он дает что-то вроде этого:

User moved slider of x (my be positive or negative)
 for first slider
   if slider -x/2  > 0 and x/2 < 100
     move this slider of -x/2
   else
     move the other slider of -x/2

 for second slider
   if slider -x/2  > 0 and x/2 < 100
     move this slider of -x/2
   else
     move the other slider of -x/2
end

Другая возможность состоит в том, чтобы считать, что сумма доступных ресурсов равна 100, ресурсы разделены на n блоков (в вашем случае 3).Когда пользователь перемещает ползунок, он фиксирует количество ресурсов в соответствующем сегменте.И поэтому вы можете либо взять ресурсы из другого сегмента, либо поместить ресурсы в эти другие сегменты.

У вас есть что-то вроде:

state 1 ; modified bucket ; new number of ressources in that bucket

modification = new number of ressources in the bucket - number of rescources in the state 1
for (int i=0 ; modification > 0 ; i++){
  i=i%nbr of buckets;
  if(bucket i != modified bucket){
    if(number of ressources in bucket i-- > 0 && number of ressources in bucket i-- < 100){
      number of ressources in bucket i--;
      modification --;
    }
  }
}

Это означает, что модификация положительнаямодифицированное ведро выше, чем раньше).Этот небольшой алгоритм будет работать с любым количеством сегментов (ползунки в вашем случае).

0 голосов
/ 22 декабря 2010

Следующий алгоритм должен быть рассмотрен и, конечно, оптимизирован. Это только то, что я собрал, и я не проверял это.

инициализируйте каждый ползунок с максимальным и минимальным значением и установите начальное значение по желанию, но с учетом этого x + y + z = 1.

[self.slider1 setMinimumValue:0.0];
[self.slider1 setMaximumValue:1.0];
[self.slider1 setValue:0.20];

[self.slider2 setMinimumValue:0.0];
[self.slider2 setMaximumValue:1.0];
[self.slider2 setValue:0.30];

[self.slider3 setMinimumValue:0.0];
[self.slider3 setMaximumValue:1.0];
[self.slider3 setValue:0.50];

Установите три ползунка на один и тот же селектор:

[self.slider1 addTarget:self action:@selector(valueChanged:) forControlEvents:UIControlEventValueChanged];
[self.slider2 addTarget:self action:@selector(valueChanged:) forControlEvents:UIControlEventValueChanged];
[self.slider3 addTarget:self action:@selector(valueChanged:) forControlEvents:UIControlEventValueChanged];

Селектор должен сделать что-то вроде этого:

- (void)valueChanged:(UISlider *)slider {
 UISlider *sliderX = nil;
 UISlider *sliderY = nil;
 UISlider *sliderZ = nil;

 if (slider == self.slider1) {
  sliderX = self.slider1;
  sliderY = self.slider2;
  sliderZ = self.slider3;
 } else if (slider == self.slider2) {
  sliderY = self.slider1;
  sliderX = self.slider2;
  sliderZ = self.slider3;
 } else {
  sliderY = self.slider1;
  sliderZ = self.slider2;
  sliderX = self.slider3;
 }

 float x = sliderX.value;
 float y = sliderY.value;
 float z = sliderZ.value;

 // x + y + z = 1 
 // Get the amout x has changed
 float oldX = 1 - y - z;
 float difference = x - oldX;

 float newY = y - difference / 2;
 float newZ = z - difference / 2;

 if (newY < 0) {
  newZ += y + newY;
  newY = 0;
 }

 if (newZ < 0) {
  newY += z + newZ;
  newZ = 0;
 }

 [sliderY setValue:newY animated:YES];
 [sliderZ setValue:newZ animated:YES];
}

Если с этим кодом что-то не так, пожалуйста, дайте мне знать, и я могу это исправить!

...