Я пытаюсь реализовать пользовательский подкласс 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;
}