2012-05-03 7 views
16

Estoy tratando de implementar un UISlider personalizado (subclase de UISlider), que se comporta de forma similar al control deslizante nativo que tiene un brillo alrededor del pulgar cuando está resaltado. Aunque estoy teniendo problemas con esto.UISlider resalta estado con ancho de pulgar diferente de lo normal

El ancho (efectivo) del pulgar resaltado es obviamente mayor que el pulgar normal (debido al brillo). Si agrego 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 parece lo contrario).

Si uso thumbRectForBounds: para compensar el pulgar a alinear correctamente con el comienzo de la pista, solo empeora el problema en el otro extremo.

Si conservo las dos imágenes solo lo que necesitan (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 UIControl.state, pero parece que hay algo de magia matemática detrás de las escenas. El único lugar donde el UISlider cree que las imágenes para ambos estados se alinean perfectamente es el centro exacto.

Parece que podría necesitar implementar algunos cálculos matemáticos que determinen el desplazamiento del estado de resaltado en función de su posición relativa a lo largo de la pista. Necesitaría un desplazamiento y de cero en el centro (el UISlider centraría ambas imágenes, lo que significa que se alinearían). En los extremos, necesitaría un desplazamiento en y que compensa por completo el resplandor. Y en el medio necesitaría interpolar el desplazamiento y.

Esto parece mucho trabajo para recrear algo que el control deslizante nativo hace, así que tal vez me falta algo obvio.

actualización solución actual:

No está completamente portátil, ya que hace que se agregan algunas suposiciones sobre el tamaño de la resplandor. Estoy agregando el resplandor con una imagen en lugar de dibujarlo directamente en el CALayer. No he probado qué tan eficiente es todavía.

Básicamente creo una capa que es un cuadrado cuyas dimensiones son la altura de la imagen de estado predeterminada, centrarla sobre el pulgar y luego dibujar el resplandor (solo el resplandor, no una imagen separada de un pulgar con brillo , como se haría con una imagen de estado de hightlight) 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; 
} 
+0

http://stackoverflow.com/questions/755510/customizing-uislider-look – VSN

+0

La pregunta es principalmente respecto a la imagen de la pista, no a la imagen de pulgar. Escribir mi propio control deslizante aún puede ser la única respuesta aquí, pero dado que estoy tratando de recrear el comportamiento nativo, todavía me pregunto si hay alguna manera de evitar tener que hacer eso. – farski

Respuesta

1

en lugar de agregar efecto de brillo en la imagen, puede ser mejor agregarlo dinámicamente. puede usar CALayer para agregar efecto de brillo.

CALayer

+0

Interesante. Lo probaré, gracias. – farski

+0

Eso será bastante difícil, ya que UISlider no parece tener subvistas o subcapas a las que se pueda agregar una sombra. –

+0

Como dice Andreas, esto no es completamente directo ya que no hay acceso directo a la imagen de la miniatura, pero he encontrado una solución que parece funcionar. Gracias por la idea, Tejesh. – farski

0

Se podría rodar su propio deslizador, que no es tan complicado como puede sonar, pero aún requeriría unas pocas horas de codificación.

Sin embargo, la solución más sencilla sería la de establecer simplemente costumbre realizar un seguimiento de las imágenes, así:

  1. Crear personalizada "mínimo"/"máximo" imágenes de la pista con el acolchado (píxeles transparentes) en la parte izquierda/derecha . El relleno debe ser tan grande como el radio de su brillo menos el radio del pulgar (11pt).
  2. Aplicar imágenes a su UISlider con setMinimumTrackImage:forState: y setMaximumTrackImage:forState:
  3. Aumentar el ancho de deslizador por el tamaño del relleno añadido
0

me encontré con un problema similar con un control deslizante a medida 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 pistas 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 un relleno extra 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 combinando varias vistas en lugar de tocar las limitaciones de personalizar un UISlider. Si puede prescindir de una pista cambiante, podría duplicar mi técnica. O bien, podría manipular el marco de una UIView o dos para hacer que las pistas personalizadas se ajusten siempre que el control deslizante cambie de valor. Si necesita usar este mismo control deslizante más de una vez en su aplicación, puede empaquetar el grupo de vistas en una subclase de UIView. Dependiendo de cuán compleja sea la acción de su control deslizante, puede llegar el momento en que la elección más prudente sería hacer un control personalizado.

Cuestiones relacionadas