Personalización de botones de control UISegmented izquierdo y derecho

Estoy tratando de personalizar el siguiente control segmentado, usando una image izquierda para el primer button y una image derecha para el segundo button. ¿Cómo haría esto usando UIAppearance?

Quiero cambiar el siguiente control segmentado:

introduzca la descripción de la imagen aquí

a algo similar como a continuación:

introduzca la descripción de la imagen aquí

La razón por la que quiero usar una image personalizada es para que pueda cambiar las esquinas de los botones. Si miras el control segmentado azul, es más cuadrado (mi image tiene sus propias esquinas).

Estaba pensando en algo así pero no uso:

UIImage *leftImage = [[UIImage imageNamed:@"leftControl.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)]; UIImage *rightImage = [[UIImage imageNamed:@"rightControl.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)]; [[UISegmentedControl appearance] setBackgroundImage:leftImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault ]; [[UISegmentedControl appearance] setBackgroundImage:rightImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 

Necesita proporcionar las siguientes imágenes:

  • Fondo de segmento seleccionado (tiene dos tapas izquierda y derecha)
    introduzca la descripción de la imagen aquí
  • Fondo de segmento no seleccionado (tiene dos tapas izquierda y derecha)
    introduzca la descripción de la imagen aquí
  • segmento medio, izquierdo seleccionado, derecho no seleccionado
    introduzca la descripción de la imagen aquí
  • segmento medio, izquierda no seleccionada, derecha seleccionada
    introduzca la descripción de la imagen aquí
  • segmento medio, ambos izquierdo y derecho seleccionados
    introduzca la descripción de la imagen aquí
  • segmento medio, ambos izquierdo y derecho no seleccionados
    introduzca la descripción de la imagen aquí

Y luego usa el siguiente código para configurar:

 /* Unselected background */ UIImage *unselectedBackgroundImage = [[UIImage imageNamed:@"segment_background_unselected"] resizableImageWithCapInsets:UIEdgeInsetsMake(10, 10, 10, 10)]; [[UISegmentedControl appearance] setBackgroundImage:unselectedBackgroundImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; /* Selected background */ UIImage *selectedBackgroundImage = [[UIImage imageNamed:@"segment_background_selected"] resizableImageWithCapInsets:UIEdgeInsetsMake(10, 10, 10, 10)]; [[UISegmentedControl appearance] setBackgroundImage:selectedBackgroundImage forState:UIControlStateSelected barMetrics:UIBarMetricsDefault]; /* Image between two unselected segments */ UIImage *bothUnselectedImage = [[UIImage imageNamed:@"segment_middle_unselected"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)]; [[UISegmentedControl appearance] setDividerImage:bothUnselectedImage forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; /* Image between segment selected on the left and unselected on the right */ UIImage *leftSelectedImage = [[UIImage imageNamed:@"segment_middle_left_selected"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)]; [[UISegmentedControl appearance] setDividerImage:leftSelectedImage forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; /* Image between segment selected on the right and unselected on the left */ UIImage *rightSelectedImage = [[UIImage imageNamed:@"segment_middle_right_selected"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)]; [[UISegmentedControl appearance] setDividerImage:rightSelectedImage forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault]; 

Tenga en count que tendrá que ajustar el tamaño del casquillo en las imágenes estirables para que coincida con sus imágenes.

La respuesta de Maurizio no funcionó para mí con un control segmentado dentro de una barra de herramientas; siguió mostrando estas líneas fantasma en los controles, ya que las imágenes divisorias no eran lo suficientemente amplias.

Entonces hice el mío. Aquí están todas las imágenes que necesitará para Xcode y también puse los files de Photoshop para crear las imágenes de control segmentadas para que pueda cambiar el estilo:

https://s3.amazonaws.com/iwasrobbed/stackoverflow/Custom+Segmented+Control.zip

Ponga esto en su AppDelegate para que cambie la apariencia, utilizando las imágenes adjuntas, de todos los controles segmentados dentro de una barra de herramientas:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self customizeAppAppearance]; } - (void)customizeAppAppearance { // Toolbar [[UIToolbar appearance] setBackgroundImage:[[UIImage imageNamed:@"toolbar.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(22, 5, 22, 5)] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault]; // Segmented Controls within Toolbars // Unselected background UIImage *unselectedBackgroundImage = [[UIImage imageNamed:@"segmentInactive.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 15, 15, 15)]; [[UISegmentedControl appearanceWhenContainedIn:[UIToolbar class], nil] setBackgroundImage:unselectedBackgroundImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; // Selected background UIImage *selectedBackgroundImage = [[UIImage imageNamed:@"segmentActive.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 15, 15, 15)]; [[UISegmentedControl appearanceWhenContainedIn:[UIToolbar class], nil] setBackgroundImage:selectedBackgroundImage forState:UIControlStateSelected barMetrics:UIBarMetricsDefault]; // Image between two unselected segments UIImage *bothUnselectedImage = [[UIImage imageNamed:@"segmentBothInactive.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 10, 15, 10)]; [[UISegmentedControl appearanceWhenContainedIn:[UIToolbar class], nil] setDividerImage:bothUnselectedImage forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; // Image between segment selected on the left and unselected on the right UIImage *leftSelectedImage = [[UIImage imageNamed:@"segmentLeftActiveRightInactive.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)]; [[UISegmentedControl appearanceWhenContainedIn:[UIToolbar class], nil] setDividerImage:leftSelectedImage forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; // Image between segment selected on the right and unselected on the left UIImage *rightSelectedImage = [[UIImage imageNamed:@"segmentRightActiveLeftInactive.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)]; [[UISegmentedControl appearanceWhenContainedIn:[UIToolbar class], nil] setDividerImage:rightSelectedImage forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault]; } 

Debe crear una image de background para todos sus segmentos, y también una image que sea solo el borde izquierdo de un button, una image que sea la unión entre dos botones y una image que sea el borde correcto. Algunas de ellas deben hacerse para múltiples estados. Entonces aquí está tu list de imágenes:

  • tapa izquierda, seleccionada
  • casquillo izquierdo, no seleccionado
  • background del segmento seleccionado
  • background del segmento, no seleccionado
  • tapa derecha, seleccionada
  • tapa derecha, sin seleccionar
  • tapa del medio, izquierda seleccionada derecha no seleccionada
  • tapa del medio, izquierda no seleccionada, derecha seleccionada
  • casquillo medio, ambos seleccionados
  • casquillo medio, ambos no seleccionados

Para los casquillos medios puede ponerlos así: (text de Apple docs).

 // Image between two unselected segments. [mySegmentedControl setDividerImage:image1 forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:barMetrics]; // Image between segment selected on the left and unselected on the right. [mySegmentedControl setDividerImage:image1 forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:barMetrics]; // Image between segment selected on the right and unselected on the right. [mySegmentedControl setDividerImage:image1 forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:barMetrics]; 

Si estás usando UIAppearance , obviamente enviarías esos posts al proxy de apariencia.