2009-07-28 17 views
18

¿Alguien sabe de una manera de personalizar el aspecto de la cadena basada en UISegmentedControl? Estoy tratando de establecer el color de fondo de la celda y el color del texto de manera diferente dependiendo del estado seleccionado del elemento.Personalizar los colores de un UISegmentedControl

Como alternativa, ¿conoce alguna forma de crear UIImages sobre la marcha para incluir cadenas personalizadas? (por ejemplo, crear uiimage con fondo blanco, texto superpuesto, agregar al control segmentado).

sé que sólo puede tener cadenas o imágenes en el control segmentado ...

Salud!

Respuesta

17

UISegmentedControl tiene una propiedad tintColor - esto le permite cambiar de qué color es el control, pero no el "estilo" general (la redondeada, forma biselada):

segmentedControl.tintColor = [UIColor blueColor]; 

En cuanto a la creación de la UIImages Fly, se puede crear un CGContext, hacer lo dibujo que se necesita en ese contexto (incluyendo cuerdas) y, a continuación, obtener un UIImage de CGImage del contexto:

CGContextRef drawContext = CGBitmapContextCreate(<many parameters>); 
//do drawing here 
CGImageRef finalImage = CGBitmapContextCreateImage(drawContext); 
UIImage *cellImage = [UIImage finalImage]; 
10
segmentedControl.tintColor = [UIColor colorWithRed:0.61176f green:0.61176f blue:0.61176f alpha:1.0f]; 

segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar; 
9

Todo lo que tiene que hacer es:

// Get an array of the subviews of a UISegmentedControl, for example myUISegmentedControl: 

NSArray *arri = [myUISegmentedControl subviews]; 

// Change the tintColor of each subview within the array: 

[[arri objectAtIndex:0] setTintColor:[UIColor redColor]]; 

[[arri objectAtIndex:1] setTintColor:[UIColor greenColor]]; 
+0

no funciona para mí –

+1

Trabajado perfectamente en iOS 7 ... ¡eres increíble! – CommaToast

+1

Solución buena cosas buenas – DogCoffee

7

La mayoría de las respuestas aquí no contesta la pregunta específica de cómo configurar un botón de color basado en el estado seleccionado que implica otro color que se desea para el estado no seleccionado. Luché con esto por bastante tiempo y quería compartir mi solución para que otros la usen.

Mi ejemplo utiliza un UISegmentedControl con tres segmentos. El color no seleccionado para los tres debe ser el mismo para darle un aspecto uniforme. El estado seleccionado para el primer y último segmento tiene colores únicos.

enter image description here

La cuestión es que el control segmentado no está garantizado a estar en el mismo orden que los colores se mezclarán mientras selecciona un lado a otro. Dan publicó una solución que usa etiquetas, pero lamentablemente ya no se garantiza que funcione para iOS 6 en adelante.

La mayor parte de este código está tomado de this post. Lo cambié ligeramente para tener colores seleccionados únicos.

Lo que hace que el trabajo es la clasificación, pero tome nota de estas 2 líneas importantes para configurar el color seleccionado:

NSInteger selectedIdx = betterSegmentedControl.selectedSegmentIndex; 
[[sortedViews objectAtIndex:selectedIdx] setTintColor:[self.segmentColors objectAtIndex:selectedIdx]]; 

- (void) updateSegmentColors 
{ 
    UIColor *checkColor = [UIColor colorWithRed: 29/255.0 green:166/255.0 blue:47/255.0 alpha:1.0]; 
    NSArray *segmentColors = [[NSArray alloc] initWithObjects:checkColor, [UIColor blueColor], [UIColor redColor], nil]; 

    UISegmentedControl *betterSegmentedControl = self.StatusControl; 

    // Get number of segments 
    NSUInteger numSegments = [betterSegmentedControl.subviews count]; 

    // Reset segment's color (non selected color) 
    for(int i = 0; i < numSegments; i++) { 
     // reset color 
     [[betterSegmentedControl.subviews objectAtIndex:i] setTintColor:nil]; 
     [[betterSegmentedControl.subviews objectAtIndex:i] setTintColor:[UIColor blueColor]]; 
    } 

    // Sort segments from left to right 
    NSArray *sortedViews = [betterSegmentedControl.subviews sortedArrayUsingFunction:compareViewsByOrigin context:NULL]; 

    // Change color of selected segment 
    NSInteger selectedIdx = betterSegmentedControl.selectedSegmentIndex; 
    [[sortedViews objectAtIndex:selectedIdx] setTintColor:[self.segmentColors objectAtIndex:selectedIdx]]; 

    // Remove all original segments from the control 
    for (id view in betterSegmentedControl.subviews) { 
     [view removeFromSuperview]; 
    } 

    // Append sorted and colored segments to the control 
    for (id view in sortedViews) { 
     [betterSegmentedControl addSubview:view]; 
    } 
} 


NSInteger static compareViewsByOrigin(id sp1, id sp2, void *context) 
{ 
    // UISegmentedControl segments use UISegment objects (private API). But we can safely cast them to UIView objects. 
    float v1 = ((UIView *)sp1).frame.origin.x; 
    float v2 = ((UIView *)sp2).frame.origin.x; 
    if (v1 < v2) 
     return NSOrderedAscending; 
    else if (v1 > v2) 
     return NSOrderedDescending; 
    else 
     return NSOrderedSame; 
} 

coloqué el código en su propio método, ya Estoy cargando estos controles segmentados en una vista de tabla y necesito ejecutarlos durante la carga (estados existentes del almacenamiento) y cuando un usuario cambia una selección. Ahora solo necesito llamar al [Self updateSegmentColors]; cuando algo cambia.

1

Pude hacerlo a través de Interface Builder en XCode 6.Se adjunta la propiedad tinte:

enter image description here

6

La mejor manera que he encontrado de hacer algo como esto está estableciendo diferentes atributos para diferentes UIControlStates en el control segmentado.

self.segmentedControl.tintColor = [UIColor cb_Grey1Color]; 
self.segmentedControl.backgroundColor = [UIColor cb_Grey3Color]; 
NSDictionary *selectedAttributes = [NSDictionary dictionaryWithObjectsAndKeys: 
            [UIFont cbGothamBookFontWithSize:13.0], NSFontAttributeName, 
            [UIColor whiteColor], NSForegroundColorAttributeName, 
            [UIColor cb_Grey1Color], NSBackgroundColorAttributeName, nil]; 
[self.segmentedControl setTitleTextAttributes:selectedAttributes forState:UIControlStateSelected]; 
NSDictionary *unselectedAttributes = [NSDictionary dictionaryWithObjectsAndKeys: 
             [UIFont cbGothamBookFontWithSize:13.0], NSFontAttributeName, 
             [UIColor cb_Grey2Color], NSForegroundColorAttributeName, 
             [UIColor cb_Grey3Color], NSBackgroundColorAttributeName, nil]; 
[self.segmentedControl setTitleTextAttributes:unselectedAttributes forState:UIControlStateNormal]; 
+0

BackgroundColorAttribute simplemente cambia el fondo del título –

2

Aquí es un ejemplo de código que funciona con iOS9, pero es un truco, y podría no funcionar en las versiones posteriores:

UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"Title1", @"Title2"]]; 
for (id segment in [segmentedControl subviews]) 
{ 
    for (id view in [segment subviews]) 
    { 
     NSString *desc = [view description]; 
     if ([desc containsString:@"UISegmentLabel"]) 
     { 
      [segment setTintColor:([desc containsString:@"Title1"] ? [UIColor blueColor] : [UIColor greenColor])]; 
     } 
    } 
} 
0

que quería lograr algo similar - establecer el color de fondo de el segmento seleccionado a un color, mientras que el 'contorno' del resto de los segmentos era de un color diferente.

Tomando mucho de la respuesta de Portland Runner, la idea es subclasificar el UISegmentedControl y anular 2 métodos tanto para el estilo inicial como para capturar el evento de cambio para darle un estilo automático a medida que el usuario selecciona diferentes segmentos.

- (void)layoutSubviews { 
    [super layoutSubviews]; 
    [self updateSegmentColors]; 
} 
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    [super touchesEnded:touches withEvent:event]; 
    [self updateSegmentColors]; 
} 
- (void)updateSegmentColors { 
    NSArray* segments = [self.subviews sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { 
     // UISegmentedControl segments use UISegment objects (private API). But we can safely cast them to UIView objects. 
     float v1 = ((UIView *)obj1).frame.origin.x; 
     float v2 = ((UIView *)obj2).frame.origin.x; 
     if (v1 < v2) return NSOrderedAscending; 
     else if (v1 > v2) return NSOrderedDescending; 
     else return NSOrderedSame; 
    }]; 
    for (int i=0; i<segments.count; i++) { 
     if (i == self.selectedSegmentIndex) { 
      [segments[i] setTintColor:[UIColor redColor]]; 
     } else { 
      [segments[i] setTintColor:[UIColor grayColor]]; 
     } 
    } 
} 
0

fuente rápida y veloz color 3 4 si desea cambiar

Para el artículo no seleccionados

segcntrl.setTitleTextAttributes(titleTextAttributes, for: .normal) 

Para el artículo seleccionado

segcntrl.setTitleTextAttributes(titleTextAttributes, for: .selected) 
Cuestiones relacionadas