Как заставить UISlider реагировать на события касания на дорожке выше и ниже ползунка большого пальца

У меня есть UISlider шириной 284 пикселя с диапазоном 0-25. Пользователю необходимо выбрать значение с точностью до 1 знака после запятой (скажем, 12,3), что возможно при осторожном вращении пальца, но это неудобно и имеет тенденцию изменять значение, когда вы поднимаете палец.

Я пытаюсь сделать так, чтобы ползунок можно было перемещать вверх или вниз с шагом 0,1 дюйма, нажимая на направляющую ползунка выше или ниже большого пальца. Я уверен, что это возможно, но, поскольку это мой первый проект xcode, я борюсь. Может кто-то указать мне верное направление?


person Bruce Alport    schedule 30.06.2010    source источник
comment
Это не совсем относится к вашему вопросу, но вам следует проверить OBSlider: oleb.net/blog/2011/01/   -  person overboming    schedule 17.02.2011


Ответы (4)


На ум приходит пара вариантов:

  1. Создайте невидимые кнопки и разместите их, чтобы получать эти клики
  2. Подкласс UISlider и перехватывать методы touchesBegan и т.д. Определите, хотите ли вы ответить на удар, основываясь на его местоположении, или вызовите функцию супера. Возможно, вам придется расширить рамку, чтобы включить в нее то, к чему вы прикасаетесь.

Я не уверен, что создание нестандартной (особенно невидимой!) реализации — это хорошая идея, однако я бы рекомендовал вам добавить видимые кнопки для тонкой настройки. Простая стрелка вверх/вниз в сторону может помочь. Также подумайте, нужен ли вам UISlider вообще, учитывая, что он недостаточно хорошо работает для вас.

person Nicholas M T Elliott    schedule 30.06.2010
comment
Вау, это было быстро! Я слышал, что вы говорите о нестандартной реализации, но я чувствовал, что поведение было логичным, хотя и невидимым. Если я подкласс UISlider, могу ли я выборочно перехватывать только нажатия? Я изо всех сил пытаюсь понять цепочку ответов на сенсорные события. - person Bruce Alport; 01.07.2010
comment
Если вы создадите подкласс UISlider, только функции, которые вы реализуете, будут перехватывать вызовы — все остальное будет передано суперклассу (UISlider). Поэтому, если вы реализуете только touchesBegan, вы будете перехватывать только события касания. См. документацию UIResponder для функций касания, которые вы, возможно, захотите реализовать. Опять же, если вы не хотите перехватывать вызов (например, для прикосновений непосредственно к ползунку), вызовите [super touchesBegan:...] и позвольте надклассу UISlider обработать его. - person Nicholas M T Elliott; 01.07.2010

Я думаю, что лучшее решение - просто создать подкласс UISLider и повторно реализовать

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event

возвращая YES, когда событие касания находится внутри границ ползунка.

person Nicolas Buquet    schedule 26.06.2012

Давняя проблема с элементом управления UISlider в iPhone OS заключается в том, что вы не можете сделать его выше. В частности, вы можете сделать его выше, указав более высокие изображения для его большого пальца и трека, но сенсорная область останется крошечной высотой 23 пикселя.

Что вам нужно сделать, так это создать подкласс UISlider и переопределить pointInside в вашем классе:

// How many extra touchable pixels you want above and below the 23px slider
#define SIZE_EXTENSION_Y 10

- (BOOL) pointInside:(CGPoint)point withEvent:(UIEvent*)event {
    CGRect bounds = self.bounds;
    bounds = CGRectInset(bounds, 0, SIZE_EXTENSION_Y);
    return CGRectContainsPoint(bounds, point);
}

В Interface Builder установите ползунок для использования вашего нового подкласса UISlider, и теперь у вас есть ползунок с сенсорной высотой 43 пикселя.

person Allen Pike    schedule 01.07.2010
comment
Вы не можете сделать ползунок выше в редакторе пера (Interface Builder), но вы можете сделать его выше в коде. - person matt; 01.01.2011
comment
У меня работает: я просто установил рамку нужной высоты в коде с остальным кодом, который настроил слайдер с моими пользовательскими изображениями. У меня была проблема, когда касания не работали ниже определенной точки, но я обнаружил, что это было связано с тем, что UIView обертывал UISlider, который не имел надлежащей высоты. Он обрезал настроенный слайдер. Зафиксировав высоту содержащего UIView, я смог решить проблему касания/высоты и удалил пользовательский класс MySlider, который пытался использовать для решения проблемы. - person Brennan; 17.02.2011
comment
Не работает, если не сочетается с - (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event - person jjxtra; 23.07.2012
comment
Расширение размера должно быть ОТРИЦАТЕЛЬНЫМ, иначе вставка фактически УМЕНЬШАЕТ сенсорные пиксели: #define SIZE_EXTENSION_Y -10 (проверено с iOS 5 и iOS 6) - person Wirsing; 15.08.2013

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

CGRect sliderFrame = self.mySlider.frame;
sliderFrame.size.height = 42.0;
[self.mySlider setFrame:sliderFrame];
person Brennan    schedule 17.02.2011
comment
Хороший совет, спасибо, Бреннан. Некоторые пользователи считают ползунки нечувствительными (думаю, пальцы сухие), и увеличение сенсорной области определенно помогло. Как оказалось, моя проблема заключалась в том, чтобы ползунок реагировал на прикосновения. - person Bruce Alport; 18.02.2011
comment
Не удалось заставить это решение работать на меня, хотя оно казалось довольно простым. - person Brett; 20.05.2013