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

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

Я узнал, как это сделать, например:

UIImage *thumb = [UIImage imageNamed:@"newThumbImage_64px.png"]; [self.slider setThumbImage:thumb forState:UIControlStateNormal]; [self.slider setThumbImage:thumb forState:UIControlStateHighlighted]; [thumb release]; 

Чтобы рассчитать соответствующее значение, мне нужно знать, где падает центральная точка большого пальца при его манипулировании. И точка должна быть в координатах супервизора.

Глядя на документы UISlider , я не видел никаких свойств, которые отслеживали это.

Есть ли простой способ вычислить это или может быть получен из какого-либо существующего значения (ов)?

Это вернет правильную позицию X центра большого пальца изображения UISlider в поле зрения координат:

 - (float)xPositionFromSliderValue:(UISlider *)aSlider { float sliderRange = aSlider.frame.size.width - aSlider.currentThumbImage.size.width; float sliderOrigin = aSlider.frame.origin.x + (aSlider.currentThumbImage.size.width / 2.0); float sliderValueToPixels = (((aSlider.value - aSlider.minimumValue)/(aSlider.maximumValue - aSlider.minimumValue)) * sliderRange) + sliderOrigin; return sliderValueToPixels; } 

Поместите его в свой controller и используйте его так: (предполагает свойство с именем слайдер)

 float x = [self xPositionFromSliderValue:self.slider]; 

Я пробовал это после прочтения приведенного выше предложения –

 yourLabel = [[UILabel alloc]initWithFrame:....]; //Call this method on Slider value change event -(void)sliderValueChanged{ CGRect trackRect = [self.slider trackRectForBounds:self.slider.bounds]; CGRect thumbRect = [self.slider thumbRectForBounds:self.slider.bounds trackRect:trackRect value:self.slider.value]; yourLabel.center = CGPointMake(thumbRect.origin.x + self.slider.frame.origin.x, self.slider.frame.origin.y - 20); } 

Для версии Swift

 func sliderValueChanged() -> Void { let trackRect = self.slider.trackRect(forBounds: self.slider.bounds) let thumbRect = self.slider.thumbRect(forBounds: self.slider.bounds, trackRect: trackRect, value: self.slider.value) yourLabel.center = CGPoint(x: thumbRect.origin.x + self.slider.frame.origin.x + 30, y: self.slider.frame.origin.y - 60) } 

Я мог бы получить наиболее точное значение, используя этот fragment.

Swift 3

 extension UISlider { var thumbCenterX: CGFloat { let trackRect = self.trackRect(forBounds: frame) let thumbRect = self.thumbRect(forBounds: bounds, trackRect: trackRect, value: value) return thumbRect.midX } } 

Я хотел бы знать, почему никто из вас не дает самый простой ответ, который заключается в чтении руководства. Вы можете точно вычислить все эти значения, а также УБЕДИТЕСЬ, ЧТО ОНИ ОСТАЛИТЬ, ЧТО ПУТЬ, просто используя методы:

 - (CGRect)trackRectForBounds:(CGRect)bounds - (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value 

которые вы можете легко найти в документации разработчика.

Если изображение большого пальца изменяется и вы хотите изменить его расположение, вы подclassифицируете и переопределяете эти методы. Первый дает вам прямоугольник, в котором большой палец может перемещать второе положение самого пальца.

Лучше использовать -[UIView convertRect:fromView:] . Это проще и проще без каких-либо сложных вычислений:

 - (IBAction)scrub:(UISlider *)sender { CGRect _thumbRect = [sender thumbRectForBounds:sender.bounds trackRect:[sender trackRectForBounds:sender.bounds] value:sender.value]; CGRect thumbRect = [self.view convertRect:_thumbRect fromView:sender]; // Use the rect to display a popover (pre iOS 8 code) [self.popover dismissPopoverAnimated:NO]; self.popover = [[UIPopoverController alloc] initWithContentViewController:[UIViewController new]]; [self.popover presentPopoverFromRect:thumbRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown|UIPopoverArrowDirectionUp animated:YES]; } 

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

  - (float)mapValueInIntervalInPercents: (float)value min: (float)minimum max: (float)maximum { return (100 / (maximum - minimum)) * value - (100 * minimum)/(maximum - minimum); } - (float)xPositionFromSliderValue:(UISlider *)aSlider { float percent = [self mapValueInIntervalInPercents: aSlider.value min: aSlider.minimumValue max: aSlider.maximumValue] / 100.0; return percent * aSlider.frame.size.width - percent * aSlider.currentThumbImage.size.width + aSlider.currentThumbImage.size.width / 2; } 

Когда вы немного играете с IB и широкоформатным изображением большого пальца размером 1px, положение большого пальца точно там, где вы ожидаете:

 UIImage *thumb = [UIImage imageNamed:@"newThumbImage_64px.png"]; CGRect sliderFrame = self.slider.frame; CGFloat x = sliderFrame.origin.x + slideFrame.size.width * slider.value + thumb.size.width / 2; CGFloat y = sliderFrame.origin.y + sliderFrame.size.height / 2; return CGPointMake(x, y); 

Вот решение Swift 2.2, я создал расширение для него. Я только пробовал это с изображением по умолчанию.

 import UIKit extension UISlider { var thumbImageCenterX: CGFloat { let trackRect = trackRectForBounds(bounds) let thumbRect = thumbRectForBounds(bounds, trackRect: trackRect, value: value) return thumbRect.origin.x + thumbRect.width / 2 - frame.size.width / 2 } } 

Swift 3.0
Пожалуйста, обратитесь, если хотите.

 import UIKit extension UISlider { var trackBounds: CGRect { return trackRect(forBounds: bounds) } var trackFrame: CGRect { guard let superView = superview else { return CGRect.zero } return self.convert(trackBounds, to: superView) } var thumbBounds: CGRect { return thumbRect(forBounds: frame, trackRect: trackBounds, value: value) } var thumbFrame: CGRect { return thumbRect(forBounds: bounds, trackRect: trackFrame, value: value) } } 

Выше решение полезно, когда UISlider является горизонтальным. В недавнем проекте нам нужно использовать UISlider с углом. Поэтому мне нужно получить как x, так и y позицию. Используя ниже для вычисления оси x, y:

 - (CGPoint)xyPositionFromSliderValue:(UISlider *)aSlider WithAngle:(double)aangle{ //aangle means the dextrorotation angle compare to horizontal. float xOrigin = 0.0; float yOrigin = 0.0; float xValueToaXis=0.0; float yValueToaXis=0.0; float sliderRange = slider_width-aSlider.currentThumbImage.size.width; xOrigin = aSlider.frame.origin.x+slider_width*fabs(cos(aangle/180.0*M_PI)); yOrigin = aSlider.frame.origin.y; xValueToaXis = xOrigin + ((((((aSlider.value-aSlider.minimumValue)/(aSlider.maximumValue-aSlider.minimumValue)) * sliderRange))+(aSlider.currentThumbImage.size.width / 2.0))*cos(aangle/180.0*M_PI)) ; yValueToaXis = yOrigin + ((((((aSlider.value-aSlider.minimumValue)/(aSlider.maximumValue-aSlider.minimumValue)) * sliderRange))+(aSlider.currentThumbImage.size.width / 2.0))*sin(aangle/180.0*M_PI)); CGPoint xyPoint=CGPointMake(xValueToaXis, yValueToaXis); return xyPoint; } 

Кроме того, могу ли я создать слайдер Ranger на основе UISlider? Благодарю.

Это будет работать для того, чтобы UISlider был размещен в любом месте экрана. Большинство других решений будут работать только тогда, когда UISlider выровнен с левым краем экрана. Заметьте, я использовал frame а не bounds для thumbRect, чтобы добиться этого. И я показываю два варианта, основанных на использовании frame или bounds для trackRect

 extension UISlider { //this version will return the x coordinate in relation to the UISlider frame var thumbCenterX: CGFloat { return thumbRect(forBounds: frame, trackRect: trackRect(forBounds: bounds), value: value).midX } //this version will return the x coordinate in relation to the UISlider's containing view var thumbCenterX: CGFloat { return thumbRect(forBounds: frame, trackRect: trackRect(forBounds: frame), value: value).midX } } 
  • Как совместить прослушиватели событий с запросом на событие?
  • Что такое MVP и MVC и в чем разница?
  • Blackberry - Загрузка / Ожидание экрана с анимацией
  • как выйти из блокировки XNextEvent xlib
  • Android ViewPager с нижними точками
  • Лучший способ переключения между UISplitViewController и другими controllerами представлений?
  • Как получить экземпляр fragmentа из FragmentActivity?
  • Установка свойства Style метки WPF в коде?
  • Более эффективный способ обновления пользовательского интерфейса от службы, чем намерения?
  • MATLAB: как отображать текст в кодировке UTF-8, считанный из файла?
  • JTable Right Align Header
  • Interesting Posts

    Почему в Android не работает «System.out.println»?

    CSS отправить кнопку странного рендеринга на iPad / iPhone

    Какова мощность выхода USB-порта?

    Как заставить Visual Studio копировать DLL-файл в выходной каталог?

    Запуск VirtualBox на хосте Windows 8.1

    В чем разница между кибибатом, килобитом и килобайтом?

    Как передать целое число из одного действия в другое?

    Окно невозможно настроить после восстановления системы

    API Карт Google V3: как получить данные о границе региона (полилиния)?

    Возможно ли распознать аппаратное обеспечение (маршрутизатор или сетевую карту) только по его MAC-адресу?

    XML-схема minOccurs / maxOccurs значения по умолчанию

    xml.LoadData. Данные на корневом уровне недопустимы. Строка 1, позиция 1

    Пользовательская всплывающая панель JavaFX 2

    Предотвращение использования LibreOffice от использования интеллектуальных котировок ("") вместо (немых) прямых котировок?

    Итерирует ли ConcurrentHashMap значение streamобезопасности?

    Давайте будем гением компьютера.