2010-10-26 2 views
26

Привет, я хочу изменить цвет фона UIButton, который пользователь нажимает на кнопку.Изменить цвет фона UIButton при выделении

Я показываю цвет фона с использованием градиента, когда пользователь нажимает Мне нужно изменить цвет градиента.

[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]; 
+0

Есть хорошие ответы на этот вопрос: http://stackoverflow.com/questions/14523348/how-to-change-the-background-color-of-a-uibutton-while-its-highlight – ThomasW

ответ

36

Изменение иерархии внутреннего уровня UIButton не рекомендуется, так как оно может сломаться в будущем обновлении iOS. Кроме того, это может привести к тому, что Apple отклонит ваше приложение. Лучшим решением будет создание подкласса кнопок. Вот пример того, как сделать это:

@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 

Вы, возможно, потребуется изменить его немного, чтобы заставить его делать то, что вы хотите, но я думаю, вы получите основную идею.

+0

Может ли plz рассказать мне, что нужно делать в «// Делать пользовательский чертеж для выделенного состояния» это то же самое, что я делаю раньше – iPhoneDev

+0

Я добавил пример о том, как рисовать градиент. Если вы хотите сделать другой пользовательский чертеж, вы должны взглянуть на Руководство по программированию 2D кварца. – loomer

+0

Спасибо большое, я попробую :) – iPhoneDev

5

Я нашел этот AYUIButton на GitHub и она прекрасно работает :) Вот пример кода:

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

Попробуйте это:

[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 

} 
+0

спасибо! который работал для меня, не нужно подклассифицировать кнопку. Отличная идея! –

+0

=) рад, что вам понравилось! – henghonglee

+1

На самом деле была одна проблема - когда пользователь нажал кнопку и вытащил свой контакт из нее - кнопка остается подсвеченной, но это можно легко зафиксировать с помощью события ... DragExit. –

2

При установке TintColor Баттона это работает, когда выделено

[YourButton setTintColor:[UIColor color]]; 
+0

Не работает. – Vidhi

+0

Что вам нужно делать и в чем проблема? Опубликуйте код, если вам нужна помощь @ Види, вы проверили другие ответы? – Pach

+1

Я хотел изменить цвет фона 'UIButton', когда он постучал/выделен. Я пробовал ваш код, но он не менял цвет фона. Поэтому я закончил с решением '[btnSubmit addTarget: self action: @selector (backgroundwhite :) forControlEvents: UIControlEventTouchDown]; - (void) backgroundwhite: (id) отправитель { [отправитель setTitleColor: [UIColor blackColor] forState: UIControlStateNormal]; [отправитель комплектBackgroundColor: [UIColor whiteColor]]; } ' – Vidhi

25

Вы можете использовать этот метод для создания и надежного UII мага указанного цвета, а затем примените его к вашей кнопке. Я сделал для 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)]; 
} 

Использование:

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

Как Matthias отметил, вы можете смело использовать 1x1 изображение для фона кнопки - это будет растянуто на кнопку.

+3

Спасибо за идею. Тем не менее, я заменил рендеринг UIView прямым рисованием контекста. Например: 'CGContextSetFillColorWithColor (context, color.CGColor); CGContextFillRect (контекст, CGRectMake (0, 0, 1, 1)); '(я использовал 1,1 как размер, потому что я создал изображение 1x1. UIButton растянет изображение.) –

+0

Да, CGContextSetFillColorWithColor намного лучше! –

+1

Я обновил ответ –

0

Swift

Расширение для UIButton, которые позволяют задать цвет фона для каждого состояния:

https://github.com/acani/UIButtonBackgroundColor

Пожалуйста, обратите внимание, что для Iphone 6 плюс вы должны изменить следующее, внутри расширения в. быстродействующий класс, который исправит его для всех версий:

//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) 
Смежные вопросы