Создание вращающегося (вертикального) UISlider выглядит красиво - PullRequest
2 голосов
/ 25 декабря 2011

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

Когда я на самом деле пользуюсь им, мой слайдер выглядит очень неточным и безобразным:

Vertical UI slider issue

Кроме того, чтобы начать с нуля совершенно новый NSControl, построенный с нуля как вертикальный слайдер, есть ли у кого-нибудь идеи, как сделать так, чтобы вертикальный слайдер пользовательского интерфейса выглядел менее псевдонимом?

Код, используемый для создания слайдера:

_slider = [[UISlider alloc] initWithFrame:CGRectMake(0, 0, kWTFSliderHeight, 10)];
_slider.transform = CGAffineTransformMakeRotation(M_PI * 1.5);
[self addSubview:_slider];

Спасибо, Дани.

Ответы [ 2 ]

6 голосов
/ 25 декабря 2011

Проблема в том, что (нетрансформированный) UISlider игнорирует запрашиваемую вами высоту кадра и использует высоту кадра 23. Например, я сделал это:

UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(80, 100, 40, 10)];
[self.view addSubview:slider];

и вот результирующий кадр:

(gdb) po [[(id)UIApp keyWindow] recursiveDescription]
<UIWindow: 0x6c1c9a0; frame = (0 0; 320 480); layer = <UIWindowLayer: 0x6c1ca30>>
   | <UIView: 0x6c23160; frame = (0 20; 320 460); autoresize = W+H; layer = <CALayer: 0x6c22750>>
   |    | <UISlider: 0x6c22ad0; frame = (80 100; 40 23); opaque = NO; layer = <CALayer: 0x6c21ae0>; value: 0.000000>

и его центральная точка:

(gdb) p (CGPoint)[0x6c22ad0 center]
$1 = {
  x = 100, 
  y = 111.5
}

Обратите внимание на то, что его центр находится в координате полу-точки на оси Y. Если вы поворачиваете ползунок на правильный угол, как это:

slider.transform = CGAffineTransformMakeRotation(M_PI * 1.5);

его центр не меняется, но его рамка меняется:

(gdb) po [[(id)UIApp keyWindow] recursiveDescription]
<UIWindow: 0x6a3a000; frame = (0 0; 320 480); layer = <UIWindowLayer: 0x6a36780>>
   | <UIView: 0x6a3c420; frame = (0 20; 320 460); autoresize = W+H; layer = <CALayer: 0x6a3ba10>>
   |    | <UISlider: 0x6a3bd90; frame = (88.5 91.5; 23 40); transform = [0, -1, 1, 0, 0, 0]; opaque = NO; layer = <CALayer: 0x6a3be20>; value: 0.000000>
...
(gdb) p (CGPoint)[0x6a3bd90 center]
$1 = {
  x = 100, 
  y = 111.5
}

Таким образом, после поворота на прямой угол вам необходимо отрегулировать центральную точку на пол-точки по осям X и Y:

CGPoint center = slider.center;
center.x += .5;
center.y += .5;
slider.center = center;

так, чтобы рамка лежала на целых границах точек:

(gdb) po [[(id)UIApp keyWindow] recursiveDescription]
<UIWindow: 0x9960aa0; frame = (0 0; 320 480); layer = <UIWindowLayer: 0x9962970>>
   | <UIView: 0x9964680; frame = (0 20; 320 460); autoresize = W+H; layer = <CALayer: 0x9963c70>>
   |    | <UISlider: 0x9964020; frame = (89 92; 23 40); transform = [0, -1, 1, 0, 0, 0]; opaque = NO; layer = <CALayer: 0x9963010>; value: 0.000000>
1 голос
/ 25 декабря 2011

Убедитесь, что положение ползунка после поворота находится на пикселях, если оно заканчивается как 0.3, 0.2, оно будет некрасивым, но если оно окажется в 1, 1, оно будет выглядеть нормально.
Конкретная проблема, которую я вижу, заключается в том, является ли значение kWTFSliderHeight нечетным. Если это так, установите его на 0,5, 0 перед вращением и проверьте

...