Состояние подсветки UISlider с шириной большого пальца, отличной от обычной

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

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

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

Если я оставлю оба изображения такой ширины, какой они должны быть (т. е. без отступов в нормальном состоянии, и они не будут одинаковой ширины ), я стал ближе.Я могу установить смещение независимо в thumbRectForBounds :на основе UIControl.state, но похоже, что за кулисами происходит какая-то математическая магия. Единственное место, где, по мнению UISlider, изображения для обоих состояний идеально совпадают, — это точный центр.

Похоже, мне может понадобиться реализовать некоторую математику, которая определяет смещение состояния выделения на основе его относительного положения на дорожке. Потребуется смещение нуля по оси y -в центре (, чтобы UISlider центрировал оба изображения, что означает их выравнивание ). В крайнем случае потребуется смещение по оси y -, которое полностью компенсирует свечение. А между ними нужно будет интерполировать смещение y -.

Мне кажется, что воссоздать то, что делает родной слайдер, очень сложно, так что, возможно, я упускаю что-то очевидное.

Обновление Текущее решение:

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

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

- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value {
  CGRect r = [super thumbRectForBounds:bounds trackRect:rect value:value];

  [thumbHighlightOverlayLayer removeFromSuperlayer];
  thumbHighlightOverlayLayer = [CALayer layer]; 

  int x = r.origin.x + (r.size.width / 2) - (r.size.height / 2);
  thumbHighlightOverlayLayer.frame = CGRectMake(x, r.origin.y, r.size.height, r.size.height);

  UIImage* thumbHighlightOverlayImage = [UIImage imageNamed:@"thumb-highlight"];
  thumbHighlightOverlayLayer.contents = (id)thumbHighlightOverlayImage.CGImage;

  switch (self.state) {
    case UIControlStateHighlighted:
      [[self layer] addSublayer:thumbHighlightOverlayLayer];
      break;
    default:
      break;
  }

  return r;
}
16
задан farski 10 May 2012 в 14:33
поделиться