objective developer apple iphone objective-c

iphone - developer - Personalizando los colores de un UISegmentedControl



swift ios documentation (9)

Aquí hay un código de muestra que funciona con iOS9, pero es un hack y puede que no funcione en 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])]; } } }

¿Alguien sabe de una manera de personalizar la apariencia de la cadena 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.

Alternativamente, ¿conoce alguna forma de crear UIImages sobre la marcha para incluir cadenas personalizadas? (Por ejemplo, crear uiimage con fondo blanco, superponer texto, agregar a control segmentado).

Sé que solo puedes tener cadenas o imágenes en el control segmentado ...

¡Aclamaciones!


Color de fuente swift 3 y swift 4 si quieres cambiar

Para artículo no seleccionado

segcntrl.setTitleTextAttributes(titleTextAttributes, for: .normal)

Para el elemento seleccionado

segcntrl.setTitleTextAttributes(titleTextAttributes, for: .selected) //MARK:- Segment color change self.segc.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.white], for: UIControlState.selected) self.segc.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.white], for: UIControlState.normal)


La mayoría de las respuestas aquí no responden a la pregunta específica de cómo configurar un color de botón según el estado seleccionado, lo que implica que se desea otro color para el estado no seleccionado. Luché con esto durante bastante tiempo y quería compartir mi solución para que otros la usaran.

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.

El problema es que no se garantiza que el control segmentado esté en el mismo orden, por lo que los colores se mezclarán a medida que se selecciona de un lado a otro. Dan publicó una solución que usa etiquetas, pero lamentablemente ya no se garantiza que funcione para iOS 6 y superiores.

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

Lo que hace que funcione 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 porque estoy cargando estos controles segmentados en una vista de tabla y necesito ejecutarlo al cargar (estados existentes desde el almacenamiento) y cuando un usuario cambia una selección. Ahora solo necesito llamar [Self updateSegmentColors]; cuando algo cambia


La mejor manera que he encontrado de hacer algo como esto es establecer 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];


Pude hacerlo a través de Interface Builder en XCode 6. La propiedad tint se adjunta:


Quería lograr algo similar: establecer el color de fondo del segmento seleccionado en un solo 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 control UISegmentedControl y anular 2 métodos para diseñar el estado inicial y capturar el evento de cambio para personalizarlo automáticamente 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]]; } } }


Todo lo que tienes 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]];


UISegmentedControl tiene una propiedad tintColor: esto le permite cambiar el color del control, pero no el "estilo" general (la forma redondeada y biselada):

segmentedControl.tintColor = [UIColor blueColor];

En cuanto a la creación de UIImages sobre la marcha, puede crear un CGContext, hacer el dibujo que necesite en ese contexto (incluidas las cadenas) y luego obtener una UIImage fuera de la CGImage del contexto:

CGContextRef drawContext = CGBitmapContextCreate(<many parameters>); //do drawing here CGImageRef finalImage = CGBitmapContextCreateImage(drawContext); UIImage *cellImage = [UIImage finalImage];


segmentedControl.tintColor = [UIColor colorWithRed:0.61176f green:0.61176f blue:0.61176f alpha:1.0f]; segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;