Я пытаюсь реализовать пользовательский UISlider (подкласс UISlider), который ведет себя аналогично встроенному слайдеру, у которого есть свечение вокруг большого пальца, когда оно выделено. У меня проблемы с этим, однако.
(эффективная) ширина выделенного пальца, очевидно, больше, чем обычный большой палец (из-за свечения). Если я добавлю прозрачное заполнение пикселей к изображению нормального состояния, так что оба изображения имеют одинаковую ширину, проблема в том, что палец нормального состояния никогда не выглядит так, как будто он достигает конца дорожки (он достигает конца, но заполнение делает оно выглядит иначе).
Если я использую thumbRectForBounds: для смещения большого пальца, чтобы правильно выравниваться с началом дорожки, это только делает проблему хуже на другом конце.
Если я сохраняю оба изображения только так широко, как они должны быть (т.е. никаких отступов в нормальном состоянии, а два не одинаковой ширины), я стал ближе. Я могу установить смещение независимо в thumbRectForBounds: на основе UIControl.state, но кажется, что там какая-то математическая магия происходит за кулисами. Единственное место, где UISlider считает, что изображения для обоих состояний идеально подходят, - это точный центр.
Кажется, мне может понадобиться реализовать некоторую математику, которая определяет смещение состояния подсветки на основе его относительного положения вдоль дорожки. Это потребует у-смещения нуля в центре (UISlider будет центрировать оба изображения, что означает, что они выравниваются). В крайних случаях для этого потребуется у-смещение, которое полностью компенсирует свечение. И между ними потребуется интерполировать смещение 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;
}