iphone - ortejos - Estado de resaltado UISlider con un ancho de pulgar diferente al normal
diastasis de ortejos (3)
En lugar de agregar un efecto de brillo en la imagen, puede ser mejor agregarlo dinámicamente. Puedes usar CALayer para agregar un efecto de resplandor.
Estoy intentando implementar un UISlider personalizado (subclase de UISlider), que se comporta de manera similar al control deslizante nativo que tiene un brillo alrededor del pulgar cuando está resaltado. Aunque estoy teniendo problemas con esto.
El ancho (efectivo) del pulgar resaltado es obviamente mayor que el pulgar normal (debido al brillo). Si agrego un relleno de píxeles transparente a la imagen de estado normal, de modo que ambas imágenes tengan el mismo ancho, el problema es que el pulgar de estado normal nunca parece que llegue al final de la pista (llega al final, pero el relleno hace que parece lo contrario).
Si uso thumbRectForBounds: para desplazar el pulgar para alinearlo correctamente con el comienzo de la pista, solo empeora el problema en el otro extremo.
Si mantengo ambas imágenes tan amplias como es necesario (es decir, sin relleno en el estado normal, y las dos no tienen el mismo ancho), me he acercado. Puedo establecer el desplazamiento de forma independiente en thumbRectForBounds: basado en el estado UIControl.state, pero parece que hay algo de magia matemática detrás de la escena. El único lugar donde UISlider cree que las imágenes de ambos estados se alinean perfectamente es el centro exacto.
Parece que es posible que necesite implementar algunos cálculos matemáticos que determinan el desplazamiento del estado de resaltado en función de su posición relativa a lo largo de la pista. Necesitaría un desplazamiento de cero en el centro (el UISlider centraría ambas imágenes, lo que significa que se alinean). En los extremos, necesitaría un desplazamiento en Y que compense completamente el brillo. Y en medio tendría que interpolar el desplazamiento de y.
Esto parece mucho trabajo para recrear algo que hace el control deslizante nativo, así que tal vez me esté perdiendo algo obvio.
Actualice la solución actual:
No es completamente portátil, ya que hace algunas suposiciones sobre el tamaño del brillo que se agrega. Estoy agregando el brillo con una imagen en lugar de dibujarla directamente en el CALayer. Todavía no he probado el rendimiento de esto.
Esencialmente, creo una capa que es un cuadrado cuyas dimensiones son la altura de la imagen del pulgar del estado predeterminado, la centro sobre el pulgar y luego dibujo el brillo (solo el brillo, no una imagen separada del pulgar con brillo, como sería hecho con una imagen de estado de luz alta) en la capa.
- (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;
}
Encontré un problema similar con un control deslizante personalizado para una de mis aplicaciones. A diferencia del control deslizante normal, la pista es una línea numérica estática, por lo que no necesito imágenes de pista mínimas y máximas separadas. Sin embargo, necesitaba un punto caliente extra grande para el pulgar. Así que hice mi imagen de pulgar con relleno adicional de píxeles transparentes, y asigné imágenes transparentes a la pista. La pista visible es solo un UIImageView detrás del control deslizante (en realidad, un UIImageView detrás de un grupo de controles deslizantes). Los bordes del control deslizante se extienden mucho más allá de los bordes de la imagen de la pista.
Mi sugerencia es hacer la construcción visual de su control deslizante previsto mediante la combinación de múltiples vistas en lugar de golpear contra las limitaciones de personalizar un UISlider. Si puedes prescindir de un cambio de pista, puedes duplicar mi técnica. O puede manipular el marco de una vista UIV o dos para hacer que las pistas personalizadas se ajusten cada vez que el control deslizante cambia de valor. Si necesita usar este mismo control deslizante más de una vez en su aplicación, puede agrupar el grupo de vistas en una subclase UIView. Dependiendo de la complejidad de su acción con el control deslizante, puede llegar un momento en el que la elección más prudente sea hacer un control personalizado.
Podría rodar su propio control deslizante, que no es tan complicado como puede parecer, pero aún requeriría unas pocas horas de codificación.
Sin embargo, la solución más sencilla sería configurar imágenes de seguimiento personalizadas también:
- Cree imágenes de pistas "mínimas" / "máximas" personalizadas con relleno (píxeles transparentes) en el lado izquierdo / derecho. El relleno debe ser tan grande como el radio de tu brillo menos el radio del pulgar (11 puntos).
- Aplique imágenes a su UISlider con
setMinimumTrackImage:forState:
ysetMaximumTrackImage:forState:
- Aumente el ancho de su control deslizante en el tamaño del relleno agregado