web-dev-qa-db-fra.com

Changer la couleur de fond de UIButton lorsque mis en surbrillance

Salut, je veux changer la couleur de fond de l'UIButton pour laquelle l'utilisateur appuie sur le bouton. 

Je montre la couleur d'arrière-plan à l'aide d'un dégradé. Lorsque l'utilisateur clique dessus, je dois changer la couleur du dégradé.

[btn setTitle: @"Next" forState:UIControlStateNormal];
CAGradientLayer *gradient = [CAGradientLayer layer];            
gradient.frame = btn.bounds;
gradient.cornerRadius = 10.0f;
locations = [[NSArray alloc] initWithObjects: 0.0f, 0.0f, 0.0f,0.0f, nil]; 
[gradient setLocations:locations];
colorNext = [[NSArray alloc] initWithObjects:…., nil]; 
gradient.colors = colorNext;
[locations release];
[btn.layer insertSublayer:gradient atIndex:0];
btn.titleLabel.textColor = [UIColor blackColor];
26
iPhoneDev

Il est déconseillé de modifier la hiérarchie de la couche interne d'un UIButton, car celle-ci pourrait être endommagée lors d'une future mise à jour d'iOS. En outre, cela peut entraîner le rejet de votre application par Apple. Une meilleure solution serait de créer une sous-classe de boutons. Voici un exemple de la façon de le faire:

@interface MyButton : UIButton
@end

@implementation MyButton

- (id)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame])
    {
        [self addObserver:self forKeyPath:@"highlighted" options:NSKeyValueObservingOptionNew context:NULL];
    }

    return self;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];

    if (self.highlighted == YES)
    {
        CGContextRef ctx = UIGraphicsGetCurrentContext();

        CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();

        const CGFloat *topGradientColorComponents = CGColorGetComponents([UIColor whiteColor].CGColor);
        const CGFloat *bottomGradientColorComponents = CGColorGetComponents([UIColor blackColor].CGColor);

        CGFloat colors[] =
        {
            topGradientColorComponents[0], topGradientColorComponents[1], topGradientColorComponents[2], topGradientColorComponents[3],
            bottomGradientColorComponents[0], bottomGradientColorComponents[1], bottomGradientColorComponents[2], bottomGradientColorComponents[3]
        };
        CGGradientRef gradient = CGGradientCreateWithColorComponents(rgb, colors, NULL, sizeof(colors) / (sizeof(colors[0]) * 4));
        CGColorSpaceRelease(rgb);

        CGContextDrawLinearGradient(ctx, gradient, CGPointMake(0, 0), CGPointMake(0, self.bounds.size.height), 0);
        CGGradientRelease(gradient);
    }
    else
    {
        // Do custom drawing for normal state
    }
}

- (void)dealloc
{
    [self removeObserver:self forKeyPath:@"highlighted"];

    [super dealloc];
}

@end

Vous aurez peut-être besoin de le modifier un peu pour qu'il fasse ce que vous voulez, mais je pense que vous avez compris l'idée de base.

36
loomer

Essaye ça:

[Button addTarget:self action:@selector(doSomething:) forControlEvents:UIControlEventTouchUpInside];
[Button addTarget:self action:@selector(setBgColorForButton:) forControlEvents:UIControlEventTouchDown];
[Button addTarget:self action:@selector(clearBgColorForButton:) forControlEvents:UIControlEventTouchDragExit];

-(void)setBgColorForButton:(UIButton*)sender
{
    [sender setBackgroundColor:[UIColor blackColor]];
}

-(void)clearBgColorForButton:(UIButton*)sender
{
    [sender setBackgroundColor:[UIColor redColor]];
}

-(void)doSomething:(UIButton*)sender
{
double delayInSeconds = 0.3;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [sender setBackgroundColor:[UIColor redColor]];
    });
    //do something

}
31
henghonglee

Vous pouvez utiliser cette méthode pour créer et solidifier UIImage de la couleur spécifiée, puis l’appliquer à votre bouton. J'ai créé une catégorie pour UIImage.

+ (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size
{
    UIGraphicsBeginImageContext(size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, (CGRect){.size = size});

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

+ (UIImage *)imageWithColor:(UIColor *)color
{
    return [UIImage imageWithColor:color size:CGSizeMake(1, 1)];
}

Usage:

[button setBackgroundImage:[UIImage imageWithColor:[UIColor redColor]]
                  forState:UIControlStateNormal];

Comme Matthias a souligné, vous pouvez utiliser en toute sécurité une image 1x1 pour l’arrière-plan de votre bouton - elle sera étirée pour remplir le bouton.

25
Pavel Alexeev

J'ai trouvé ceci AYUIButton sur GitHub et cela fonctionne parfaitement :) Voici un exemple de code:

[btn setBackgroundColor:[UIColor redColor] forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor blueColor] forState:UIControlStateHighlighted];
5
zvjerka24

Lorsque vous définissez la couleur de teinte du bouton, cela fonctionne lorsqu'il est en surbrillance 

[YourButton setTintColor:[UIColor color]];
2
Pach

Rapide

Extension pour UIButton qui vous permet de spécifier la couleur d'arrière-plan pour chaque état:

https://github.com/acani/UIButtonBackgroundColor

Veuillez noter que pour iphone 6 plus, vous devez modifier les éléments suivants, dans l'extension de la classe .Swift, qui le corrigeront pour toutes les versions:

//let rect = CGRect(x: 0, y: 0, width: 0.5, height: 0.5) comment this line
    let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
0
Juan Boero