web-dev-qa-db-fra.com

Contrôle UISegmented personnalisé

Comment créer une UISegmentedControl personnalisée?

J'ai 2 images, une qui devrait être affichée quand le segment est actif et l'autre si le segment est inactif. Puis-je remplacer le style ou quelque chose de sorte que j'ai une UISegmentedControl avec mes propres images en tant qu'arrière-plan actif/inactif?

36
Robbert

J'ai dû ajouter ce code supplémentaire, en plus d'avoir 2 états différents pour les positions "actif" et "désactivé":

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Set set segControl background to transparent
    CGRect rect = CGRectMake(0, 0, 1, 1);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
    CGContextFillRect(context, rect);
    UIImage *transparentImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    [self.segControl setBackgroundImage:transparentImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

    [self.segControl setDividerImage:transparentImage forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
}

EDIT: Parce que cela fait de la publicité, une solution plus propre consiste à utiliser [UIImage new] au lieu de créer des images transparentes, comme telles:

 [self.segControl setDividerImage:[UIImage new] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
 [self.segControl setBackgroundImage:[UIImage new] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
33
Jon

Vous pouvez utiliser les méthodes décrites dans la bibliothèque de développement iOS:

http://developer.Apple.com/library/ios/ipad/#documentation/uikit/reference/UISegmentedControl_Class/Reference/UISegmentedControl.html

Faites défiler jusqu'à la section "Personnalisation de l'apparence" . Il existe des méthodes pour définir des images d'arrière-plan pour plusieurs états de bouton, des images de séparateur de bouton, etc.

Ces méthodes ne sont disponibles que dans iOS5 et versions ultérieures.

@property tintColor  
– backgroundImageForState:barMetrics:
– setBackgroundImage:forState:barMetrics:
– contentPositionAdjustmentForSegmentType:barMetrics:
– setContentPositionAdjustment:forSegmentType:barMetrics:
– dividerImageForLeftSegmentState:rightSegmentState:barMetrics:
– setDividerImage:forLeftSegmentState:rightSegmentState:barMetrics:
– titleTextAttributesForState:
– setTitleTextAttributes:forState:
14
Bocaxica

Le moyen le plus simple serait de créer votre propre contrôle qui imite UISegmentedControl. UISegmentedControl organise simplement une série de boutons et gère leur état d'image pour vous; ça ne fait rien de spécial.

9
rpetrich

J'ai écrit quelque chose qui fonctionne comme l'explique @rpetrich sans le placer dans un tableau et, à mon avis, c'est la solution la plus simple. J'espère que quelqu'un trouve cela utile 

.h

IBOutlet UIButton *index0;
IBOutlet UIButton *index1;
IBOutlet UIButton *index2;
IBOutlet UIImageView *segMentControl;

-(IBAction)segmentSwitch:(UIButton *) buttonIndexPressed;

.m

-(IBAction)segmentSwitch:(UIButton *) buttonIndexPressed
{
    if (buttonIpressed == index0)
    {
        [segmentControl setImage:[UIImage imageNamed:@"Seg1Sel.png"]];
        NSLog(@"index 0 pushed");

        index0.enabled = NO;
        index1.enabled = YES;
        index2.enabled = YES;        
    }
    else if (buttonIpressed == index1)
    {
         [segmentControl setImage:[UIImage imageNamed:@"Seg2Sel.png"]];
         NSLog(@"index 1 pushed");

         index0.enabled = YES;
         index1.enabled = NO;
         index2.enabled = YES;
    }
    else if (buttonIpressed == index2)
    {
        [segmentControl setImage:[UIImage imageNamed:@"Seg3Sel.png"]];
        NSLog(@"index 2 pushed");

        index0.enabled = YES;
        index1.enabled = YES;
        index2.enabled = NO;
    }
}
6
FreeAppl3

Oui, vous avez besoin de 2 images (activées et désactivées) pour chaque section de la barre de segments . (4 segments ... 8 images.) Mais cela vous permet de définir 16 choix au total! (Tous ne consomment qu'une seule ligne dans votre interface graphique.)

J'ai tout fonctionne SAUF ... comment cachez-vous les graphiques de barre de segment d'origine?

Impossible de définir alpha sur 0. (Cela masquera également vos images.)

Impossible de définir "tintClear" sur "clear". (Vous ne savez pas pourquoi cela le rend noir et blanc.)

Impossible de le définir sur "caché" ... rien ne fonctionnera du tout.

Impossible de définir "background" sur "clear". (L'arrière-plan n'est PAS le graphique segmentbar.)

6
Patricia

ça marche très bien

[segmentControl setImage:[UIImage imageNamed:@"Rolenew.png"] forSegmentAtIndex:0];
2
virata

Essayez HMSegmentedControl, il autorise également les images et d’autres paramètres. Disponible à https://github.com/HeshamMegid/HMSegmentedControl

1
poima

Pour ce faire, vous devez écouter le fichier UIControlEventValueChanged et modifier vous-même l'image. Vous ne devriez pas avoir besoin de sous-classer UISegmentedControl - rappelez-vous la composition plutôt que l'héritage est préférable!

0
groundhog

Swift 3.0 Version de la réponse de Jon.

var transparentImage = UIGraphicsGetImageFromCurrentImageContext() as? UIImage
UIGraphicsEndImageContext()
segControl.setBackgroundImage(transparentImage, for: .normal, barMetrics: .default)
segControl.setDividerImage(transparentImage, forLeftSegmentState: .normal, rightSegmentState: .normal, barMetrics: .default)
0
Saranjith