Як змінити колір тла UIButton під час його виділення?


236

У якийсь момент у моєму додатку у мене з’являється виділення UIButton(наприклад, коли у користувача є палець на кнопку), і мені потрібно змінити колір тла під час виділення кнопки (так, поки палець користувача все ще знаходиться на кнопці) .

Я спробував таке:

_button.backgroundColor = [UIColor redColor];

Але це не працює. Колір залишається колишнім. Я спробував той самий фрагмент коду, коли кнопка не виділена, і вона працює добре. Я також спробував зателефонувати -setNeedsDisplayпісля зміни кольору, це не мало ніякого ефекту.

Як змусити кнопку змінити колір тла?


Відповіді:


411

Ви можете перевизначити UIButton«S setHighlightedметод.

Ціль-С

- (void)setHighlighted:(BOOL)highlighted {
    [super setHighlighted:highlighted];

    if (highlighted) {
        self.backgroundColor = UIColorFromRGB(0x387038);
    } else {
        self.backgroundColor = UIColorFromRGB(0x5bb75b);
    }
}

Swift 3.0 та Swift 4.1

override open var isHighlighted: Bool {
    didSet {
        backgroundColor = isHighlighted ? UIColor.black : UIColor.white
    }
}

Так. Це якийсь приємний спосіб зробити це. Тому що ви можете визначити кілька подібних кнопок.
Пол Бревчинський

3
Просто питання для новачків, де ви б підкласирували цей метод кнопок? Якщо у мене є кнопка в контролері подання з назвою ConversionViewController, як я можу налаштувати кнопку, щоб змінити колір фону, коли підсвічується або натискається? Чи я б підкласифікувати набірHIlilight у COnversionViewController?
Beanno1116

Тож є одна проблема з цією відповіддю, яку я знайшов. Якщо ви хочете, щоб той самий колір був доступний, коли ви вибираєте кнопку, тоді setHighlight викликається після setSelected і, таким чином, буде замінено будь-який обраний у вас стиль. Рішення вище може бути кращим, якщо ви також хочете вибрати кнопку
HaloZero

3
@YakivKovalskiy припускаючи, що ви використовуєте підклас, ви можете додати два властивості UIColor, наприклад, normalBackground та виділеноBackground, а потім призначити відповідно self.backgroundColor = normalBackground або виділеноBackground. Не забудьте додати метод init для зручності використання, наприклад, initWithBackground: highlightBackground:
SK.

2
Приємне рішення, лише одна пропозиція:backgroundColor = isHighlighted ? .lightGray : .white
Fantini

298

Не впевнений, чи вирішує цей спосіб те, що ви хочете, чи відповідає вашому загальному ландшафту розвитку, але першим, що я спробую, було б змінити колір фону кнопки під час події touchDown.

Варіант 1:

Вам потрібно буде дві події для зйомки, для яких UIControlEventTouchDown буде, коли користувач натисне кнопку. UIControlEventTouchUpInside та UIControlEventTouchUpOutside будуть, коли вони відпустять кнопку, щоб повернути її до нормального стану

UIButton *myButton =  [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setFrame:CGRectMake(10.0f, 10.0f, 100.0f, 20.f)];
[myButton setBackgroundColor:[UIColor blueColor]];
[myButton setTitle:@"click me:" forState:UIControlStateNormal];
[myButton setTitle:@"changed" forState:UIControlStateHighlighted];
[myButton addTarget:self action:@selector(buttonHighlight:) forControlEvents:UIControlEventTouchDown];
[myButton addTarget:self action:@selector(buttonNormal:) forControlEvents:UIControlEventTouchUpInside];

Варіант 2:

Поверніть зображення, зроблене з потрібного кольору виділення. Це також може бути категорія.

+ (UIImage *)imageWithColor:(UIColor *)color {
   CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
   UIGraphicsBeginImageContext(rect.size);
   CGContextRef context = UIGraphicsGetCurrentContext();

   CGContextSetFillColorWithColor(context, [color CGColor]);
   CGContextFillRect(context, rect);

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

   return image;
}

а потім змінити виділений стан кнопки:

[myButton setBackgroundImage:[self imageWithColor:[UIColor greenColor]] forState:UIControlStateHighlighted];

3
Додайте UIControlEventTouchUpOutside та UIControlEventTouchCancel до кнопкиHighlight: список подій, і він працюватиме завжди.
Євген Бодунов

Варіант другий - найкраще, що я знайшов поки що. Я думаю, однак, що розкадровки в цьому випадку мають свої переваги!
Джек Соломон

Відповідь Томаса краща, і це я також використовую
Ван Дю Тран

26
Якщо ви використовуєте layer.cornerRadiusта переходите з опцією №2, вам потрібно встановити clipsToBoundsзначення "true", щоб також закруглити кути зображення.
Скай

3
Якщо хтось зупиняється і потребує відповіді у Свіфті: stackoverflow.com/questions/26600980/…
зимував

94

Не потрібно переосмислювати highlightedяк обчислене властивість. Ви можете використовувати спостерігач властивостей, щоб запустити зміну кольору тла:

override var highlighted: Bool {
    didSet {
        backgroundColor = highlighted ? UIColor.lightGrayColor() : UIColor.whiteColor()
    }
}

Швидкий 4

override open var isHighlighted: Bool {
    didSet {
        backgroundColor = isHighlighted ? UIColor.lightGray : UIColor.white
    }
}

1
Я ніколи не використовував подібний функціонал. Чи можете ви пояснити, куди це йде? Чи це у кнопці IBActionPress або у viewDidLoad?
Дейв Г

Що робити, якщо у мене є кілька UIB-кнопок з різними кольорами?
Славчо

6
@Dave G, ви створюєте новий підклас UIButton, натискаючи File>New>File>Cocoa Touch Classта встановлюючи його subclass of UIButton. Назвіть файл для ex CustomButton, який стане і ім'ям файлу, і іменем класу. Всередину цього файлу покладіть override var highlightedнаведений вище код. Останній крок, встановіть UIButton на Interface Builder для використання цього CustomButtonпідкласу, перейшовши на сторінку властивостей, де написано "Спеціальний клас" та є спадне поле. Це буде говорити "UIButton" сірими літерами. У спадному списку повинно бути вказано CustomButton. Виберіть це, і тепер кнопка підкласифікована.
Джеймс Тумі

Чому ніхто не згадав, що сетер викликається лише при натисканні на кнопку, але не під час початкового макета! Тому за замовчуванням немає кольору, поки ви не натиснете кнопку.
Дмитро

Тому для того, щоб він працював, вам також потрібно явно зателефонувати isHighlighted = falseдесь на початку (наприклад, про ініціалізацію).
Дмитро

49

Зручне розширення у Swift:

extension UIButton {
    private func imageWithColor(color: UIColor) -> UIImage {
        let rect = CGRectMake(0.0, 0.0, 1.0, 1.0)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()

        CGContextSetFillColorWithColor(context, color.CGColor)
        CGContextFillRect(context, rect)

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image
    }

    func setBackgroundColor(color: UIColor, forUIControlState state: UIControlState) {
        self.setBackgroundImage(imageWithColor(color), forState: state)
    }
}

Swift 3.0

extension UIButton {
    private func imageWithColor(color: UIColor) -> UIImage? {
        let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()

        context?.setFillColor(color.cgColor)
        context?.fill(rect)

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image
    }

    func setBackgroundColor(_ color: UIColor, for state: UIControlState) {
        self.setBackgroundImage(imageWithColor(color: color), for: state)
    }
}

45

У Swift ви можете замінити аксесуар виділеної (або вибраної) властивості, а не змінити метод setHighlight

override var highlighted: Bool {
        get {
            return super.highlighted
        }
        set {
            if newValue {
                backgroundColor = UIColor.blackColor()
            }
            else {
                backgroundColor = UIColor.whiteColor()
            }
            super.highlighted = newValue
        }
    }

Це повністю працює, але я збентежений, як ви змогли це зрозуміти? Наскільки я можу сказати, параметри відсутні в документації або UIButton.h.
shimizu

1
Це швидкий синтаксис, який імітує поведінку переважаючого setHightlight у об'єкті c. Дивіться документацію про обчислювані властивості тут developer.apple.com/library/ios/documentation/Swift/Conceptual/…
Джейк Холл

11
Швидко можна скористатися didSet
гребля

1
Я додав приклад із спостерігачем власності: stackoverflow.com/a/29186375/195173 .
Олексій Мджаликс

Я думаю, що запитував @shimizu - це те, як ти знаєш, що highlightedце власність у UIButton. Відповідь полягає в тому, що це власність на UIControl, від якої UIButton успадковує.
Адам Джонс

25

Перевизначення виділеної змінної. Додавання @IBInspectableдає змогу редагувати виділений фон Colorlor у розкадровці, який теж чудовий.

class BackgroundHighlightedButton: UIButton {
    @IBInspectable var highlightedBackgroundColor :UIColor?
    @IBInspectable var nonHighlightedBackgroundColor :UIColor?
    override var highlighted :Bool {
        get {
            return super.highlighted
        }
        set {
            if newValue {
                self.backgroundColor = highlightedBackgroundColor
            }
            else {
                self.backgroundColor = nonHighlightedBackgroundColor
            }
            super.highlighted = newValue
        }
    }
}

20

більш компактне рішення (на основі відповіді @ aleksejs-mjaliks ):

Швидкий 3/4 + :

override var isHighlighted: Bool {
    didSet {
        backgroundColor = isHighlighted ? .lightGray : .white
    }
}

Швидкий 2:

override var highlighted: Bool {
    didSet {
        backgroundColor = highlighted ? UIColor.lightGrayColor() : UIColor.whiteColor()
    }
}

Якщо ви не хочете перекривати, це оновлена ​​версія відповіді @ timur-bernikowich ( Swift 4.2 ):

extension UIButton {
  func setBackgroundColor(_ color: UIColor, forState controlState: UIControl.State) {
    let colorImage = UIGraphicsImageRenderer(size: CGSize(width: 1, height: 1)).image { _ in
      color.setFill()
      UIBezierPath(rect: CGRect(x: 0, y: 0, width: 1, height: 1)).fill()
    }
    setBackgroundImage(colorImage, for: controlState)
  }
}

@FedericoZanetello це відмінить isHightlight у всіх кнопках у вашому додатку, що, на мою думку, не є гарним рішенням. погано йду з відповіддю Тимура.
Усама Бін Аттик

13

Розширення UIButton із синтаксисом Swift 3+ :

extension UIButton {
    func setBackgroundColor(color: UIColor, forState: UIControlState) {
        UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
        UIGraphicsGetCurrentContext()!.setFillColor(color.cgColor)
        UIGraphicsGetCurrentContext()!.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
        let colorImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        self.setBackgroundImage(colorImage, for: forState)
    }}

Використовуйте його так:

YourButton.setBackgroundColor(color: UIColor.white, forState: .highlighted)

Оригінальна відповідь: https://stackoverflow.com/a/30604658/3659227


10

Ось підхід у Swift, використовуючи розширення UIButton для додавання IBInspectable, який називається виділенимBackgroundColor. Аналогічно підкласові, не вимагаючи підкласу.

private var HighlightedBackgroundColorKey = 0
private var NormalBackgroundColorKey = 0

extension UIButton {

    @IBInspectable var highlightedBackgroundColor: UIColor? {
        get {
            return objc_getAssociatedObject(self, &HighlightedBackgroundColorKey) as? UIColor
        }

        set(newValue) {
            objc_setAssociatedObject(self,
                &HighlightedBackgroundColorKey, newValue, UInt(OBJC_ASSOCIATION_RETAIN))
        }
    }

    private var normalBackgroundColor: UIColor? {
        get {
            return objc_getAssociatedObject(self, &NormalBackgroundColorKey) as? UIColor
        }

        set(newValue) {
            objc_setAssociatedObject(self,
                &NormalBackgroundColorKey, newValue, UInt(OBJC_ASSOCIATION_RETAIN))
        }
    }

    override public var backgroundColor: UIColor? {
        didSet {
            if !highlighted {
                normalBackgroundColor = backgroundColor
            }
        }
    }

    override public var highlighted: Bool {
        didSet {
            if let highlightedBackgroundColor = self.highlightedBackgroundColor {
                if highlighted {
                    backgroundColor = highlightedBackgroundColor
                } else {
                    backgroundColor = normalBackgroundColor
                }
            }
        }
    }
}

Я сподіваюся, що це допомагає.


1
Для swift 2.0 вам потрібно буде оновити виклик до objc_setAssociatedObject, щоб використовувати enum: objc_setAssociatedObject (self, & NormalBackgroundColorKey, newValue, .OBJC_ASSOCIATION_RETAIN)
Елі Берк

Безумовно, найкращий спосіб у Swift, якщо ви хочете зберегти все це у Storyboard.
davidethell

1
Я вважаю за краще використовувати підклас не розширення, оскільки це вплине на весь додаток
Hossam Ghareeb


9

Моє найкраще рішення для Swift 3+ без підкласифікації.

extension UIButton {
  func setBackgroundColor(_ color: UIColor, for state: UIControlState) {
    let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
    UIGraphicsBeginImageContext(rect.size)
    color.setFill()
    UIRectFill(rect)
    let colorImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    setBackgroundImage(colorImage, for: state)
  }
}

За допомогою цього розширення легко керувати кольорами для різних станів, і він автоматично вицвічує ваш звичайний колір у випадку, якщо виділений колір не надається.

button.setBackgroundColor(.red, for: .normal)

4

ОНОВЛЕННЯ:

Використовуйте бібліотеку UIButtonBackgroundColor Swift.

СТАРИЙ:

Використовуйте нижче помічники, щоб створити зображення розміром 1 px x 1 px із кольором заповнення сірого:

UIImage *image = ACUTilingImageGray(248/255.0, 1);

або колір заповнення RGB:

UIImage *image = ACUTilingImageRGB(253/255.0, 123/255.0, 43/255.0, 1);

Потім використовуйте це, imageщоб встановити фонове зображення кнопки:

[button setBackgroundImage:image forState:UIControlStateNormal];

Помічники

#pragma mark - Helpers

UIImage *ACUTilingImageGray(CGFloat gray, CGFloat alpha)
{
    return ACUTilingImage(alpha, ^(CGContextRef context) {
        CGContextSetGrayFillColor(context, gray, alpha);
    });
}

UIImage *ACUTilingImageRGB(CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha)
{
    return ACUTilingImage(alpha, ^(CGContextRef context) {
        CGContextSetRGBFillColor(context, red, green, blue, alpha);
    });
}

UIImage *ACUTilingImage(CGFloat alpha, void (^setFillColor)(CGContextRef context))
{
    CGRect rect = CGRectMake(0, 0, 0.5, 0.5);
    UIGraphicsBeginImageContextWithOptions(rect.size, alpha == 1, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    setFillColor(context);
    CGContextFillRect(context, rect);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

Примітка: ACUце префікс класу моєї статичної бібліотеки Cocoa Touch під назвою Acani Utilities, де AC - для Acani, а U - для Utilities.


4

Спробуйте це !!!!

Для TouchedDown Event встановіть один колір, а для TouchUpInside - інший.

- (IBAction)touchedDown:(id)sender {
    NSLog(@"Touched Down");
    btn1.backgroundColor=[UIColor redColor];
}

- (IBAction)touchUpInside:(id)sender {
    NSLog(@"TouchUpInside");
    btn1.backgroundColor=[UIColor whiteColor];    
}

2
Працювали для мене. Мені просто довелося додати, - (IBAction)onButtonTouchDragOutside:(UIButton *)sender {щоб переконатися, що колір не залишається, коли користувач випадково відтягує палець від кнопки.
SudoPlz

4

Підкласируйте UIButton та додайте властивості, які можна перевірити, для зручного використання (написано Swift 3.0):

final class SelectableBackgroundButton: UIButton {

    private struct Constants {
        static let animationDuration: NSTimeInterval = 0.1
    }

    @IBInspectable
    var animatedColorChange: Bool = true

    @IBInspectable
    var selectedBgColor: UIColor = UIColor.blackColor().colorWithAlphaComponent(0.2)

    @IBInspectable
    var normalBgColor: UIColor = UIColor.clearColor()

    override var selected: Bool {
        didSet {
            if animatedColorChange {
                UIView.animateWithDuration(Constants.animationDuration) {
                    self.backgroundColor = self.selected ? self.selectedBgColor : self.normalBgColor
                }
            } else {
                self.backgroundColor = selected ? selectedBgColor : normalBgColor
            }
        }
    }

    override var highlighted: Bool {
        didSet {
            if animatedColorChange {
                UIView.animateWithDuration(Constants.animationDuration) {
                    self.backgroundColor = self.highlighted ? self.selectedBgColor : self.normalBgColor
                }
            } else {
                self.backgroundColor = highlighted ? selectedBgColor : normalBgColor
            }
        }
    }
}

3

Ви можете підкласифікувати UIButton і зробити приємне дляState.

colourButton.h

#import <UIKit/UIKit.h>

@interface colourButton : UIButton

-(void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state;

@end

colorurButton.m

#import "colourButton.h"

@implementation colourButton
{
    NSMutableDictionary *colours;
}

-(id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];

    // If colours does not exist
    if(!colours)
    {
        colours = [NSMutableDictionary new];  // The dictionary is used to store the colour, the key is a text version of the ENUM
        colours[[NSString stringWithFormat:@"%lu", UIControlStateNormal]] = (UIColor*)self.backgroundColor;  // Store the original background colour
    }

    return self;
}

-(void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state
{
    // If it is normal then set the standard background here
    if(state & UIControlStateNormal)
    {
        [super setBackgroundColor:backgroundColor];
    }

    // Store the background colour for that state
    colours[[NSString stringWithFormat:@"%lu", state]]= backgroundColor;
}

-(void)setHighlighted:(BOOL)highlighted
{
    // Do original Highlight
    [super setHighlighted:highlighted];

    // Highlight with new colour OR replace with orignial
    if (highlighted && colours[[NSString stringWithFormat:@"%lu", UIControlStateHighlighted]])
    {
        self.backgroundColor = colours[[NSString stringWithFormat:@"%lu", UIControlStateHighlighted]];
    }
    else
    {
        self.backgroundColor = colours[[NSString stringWithFormat:@"%lu", UIControlStateNormal]];
    }
}

-(void)setSelected:(BOOL)selected
{
    // Do original Selected
    [super setSelected:selected];

    // Select with new colour OR replace with orignial
    if (selected && colours[[NSString stringWithFormat:@"%lu", UIControlStateSelected]])
    {
        self.backgroundColor = colours[[NSString stringWithFormat:@"%lu", UIControlStateSelected]];
    }
    else
    {
        self.backgroundColor = colours[[NSString stringWithFormat:@"%lu", UIControlStateNormal]];
    }
}

@end

Примітки (Це приклад, я знаю, що є проблеми, і ось деякі)

Я використовував NSMutableDictionay для зберігання UIColor для кожного штату, я повинен зробити неприємне перетворення тексту для ключа, оскільки UIControlState не є хорошим прямим Int. Якби там, де ви могли б ініціювати масив із такою кількістю об'єктів і використовувати стан як індекс.

Через це у багатьох виникають труднощі з, наприклад, вибраною кнопкою та відключеною кнопкою, потрібна ще якась логіка.

Інша проблема полягає в тому, що якщо ви спробуєте встановити кілька кольорів одночасно, я не намагався натиснути кнопку, але якщо ви можете це зробити, це може не спрацювати

 [btn setBackgroundColor:colour forState:UIControlStateSelected & UIControlStateHighlighted];

Я припустив, що це StoryBoard, немає init, initWithFrame, тому додайте їх, якщо вони вам потрібні.


3
extension UIButton {
    func setBackgroundColor(color: UIColor, forState: UIControl.State) {
        let size = CGSize(width: 1, height: 1)
        UIGraphicsBeginImageContext(size)
        let context = UIGraphicsGetCurrentContext()
        context?.setFillColor(color.cgColor)
        context?.fill(CGRect(origin: CGPoint.zero, size: size))
        let colorImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        setBackgroundImage(colorImage, for: forState)
    }

}

Швидкий 5 , дякую @Maverick


3

Деталі

  • Xcode 11.1 (11A1027), Swift 5

Рішення

import UIKit

extension UIColor {
    func createOnePixelImage() -> UIImage? {
        let size = CGSize(width: 1, height: 1)
        UIGraphicsBeginImageContext(size)
        defer { UIGraphicsEndImageContext() }
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        context.setFillColor(cgColor)
        context.fill(CGRect(origin: .zero, size: size))
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

extension UIButton {
    func setBackground(_ color: UIColor, for state: UIControl.State) {
        setBackgroundImage(color.createOnePixelImage(), for: state)
    }
}

Використання

button.setBackground(.green, for: .normal)

2

Спробуйте це, якщо у вас є зображення:

-(void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state;

або подивіться, чи showsTouchWhenHighlightedдостатньо для вас


Я спробував пограти з шоуTouchWhenHighlight, але це не допомогло. Я не хочу використовувати setBackgroundImage: forState :. Я насправді намагався використовувати backgroundColor, щоб не використовувати жодного зображення.
MartinMoizard

2

Я заповнив підклас UIButton , STAButton , щоб заповнити цю відкриту функціональну дірку. Доступно за ліцензією MIT. Працює для iOS 7+ (я не тестував старіші версії iOS).


2

Щоб вирішити цю проблему, я створив Категорію для обробки backgroundColorдержав UIButtons:
ButtonBackgroundColor-iOS

Ви можете встановити категорію як стручок .

Простий у використанні з Objective-C

@property (nonatomic, strong) UIButton *myButton;

...

[self.myButton bbc_backgroundColorNormal:[UIColor redColor]
                 backgroundColorSelected:[UIColor blueColor]];

Ще простіше у використанні зі Swift :

import ButtonBackgroundColor

...

let myButton:UIButton = UIButton(type:.Custom)

myButton.bbc_backgroundColorNormal(UIColor.redColor(), backgroundColorSelected: UIColor.blueColor())

Я рекомендую вам імпортувати стручок із:

platform :ios, '8.0'
use_frameworks!

pod 'ButtonBackgroundColor', '~> 1.0'

Використання use_frameworks! у вашому Podfile полегшує використання ваших стручків за допомогою Swift та target-C.

ВАЖЛИВО

Я також написав повідомлення в блозі з додатковою інформацією


2
class CustomButton: UIButton {

    override var isHighlighted: Bool {
        didSet {
            if (isHighlighted) {
                alpha = 0.5
            }
            else {
                alpha = 1
            }            
        }
    }

}


1

Спробуйте tintColor:

_button.tintColor = [UIColor redColor];

Ви впевнені, що це пов'язано в IB? Що ви отримуєте, якщо зробите NSLog(@"%@", _button);?
jjv360

1
Це не працюватиме, якщо ви використовуєте UIButtonTypeCustom.
ДжаредХ

1

Ось код Swift для вибору стану кнопки:

func imageWithColor(color:UIColor) -> UIImage {
    let rect:CGRect = CGRectMake(0.0, 0.0, 1.0, 1.0)
     UIGraphicsBeginImageContext(rect.size)
    let context:CGContextRef = UIGraphicsGetCurrentContext()!
    CGContextSetFillColorWithColor(context, color.CGColor)
    CGContextFillRect(context, rect)
    let image:UIImage = UIGraphicsGetImageFromCurrentImageContext();
    return image;
}

Приклад:

    self.button.setImage(self.imageWithColor(UIColor.blackColor()), forState: .Highlighted)

1

Запустіть його, і ви готові йти:
* в IB можна встановити proerty, і якщо не виділено виділеного фону, фон не зміниться при натисканні

private var highlightedBackgroundColors = [UIButton:UIColor]()
private var unhighlightedBackgroundColors = [UIButton:UIColor]()
extension UIButton {

    @IBInspectable var highlightedBackgroundColor: UIColor? {
        get {
            return highlightedBackgroundColors[self]
        }

        set {
            highlightedBackgroundColors[self] = newValue
        }
    }

    override open var backgroundColor: UIColor? {
        get {
            return super.backgroundColor
        }

        set {
            unhighlightedBackgroundColors[self] = newValue
            super.backgroundColor = newValue
        }
    }

    override open var isHighlighted: Bool {
        get {
            return super.isHighlighted
        }

        set {
            if highlightedBackgroundColor != nil {
                super.backgroundColor = newValue ? highlightedBackgroundColor : unhighlightedBackgroundColors[self]
            }
            super.isHighlighted = newValue
        }
    }
}

1

Нижче UIIImageрозширення буде генерувати об’єкт зображення із заданим кольоровим параметром.

extension UIImage {
    static func imageWithColor(tintColor: UIColor) -> UIImage {
        let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
        tintColor.setFill()
        UIRectFill(rect)
        let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
       }
    }

Приклад використання кнопки може бути застосований до об’єкта кнопки як:

setupButton.setBackgroundImage(UIImage.imageWithColor(tintColor: UIColor(displayP3Red: 232/255, green: 130/255, blue: 121/255, alpha: 1.0)), for: UIControlState.highlighted)

setupButton.setBackgroundImage(UIImage.imageWithColor(tintColor: UIColor(displayP3Red: 255/255, green: 194/255, blue: 190/255, alpha: 1.0)), for: UIControlState.normal)

1

Просте те, що використовуйте ТІЛЬКИ розширення UIButton

extension UIButton {

    func setBackgroundColor(color: UIColor, forState: UIControl.State) {
        self.clipsToBounds = true  // add this to maintain corner radius
        UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
        if let context = UIGraphicsGetCurrentContext() {
            context.setFillColor(color.cgColor)
            context.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
            let colorImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            self.setBackgroundImage(colorImage, for: forState)
        }
    }

}

і використовувати це

 optionButton.setBackgroundColor(color: UIColor(red:0.09, green:0.42, blue:0.82, alpha:1.0), forState: .selected)

 optionButton.setBackgroundColor(color: UIColor(red:0.96, green:0.96, blue:0.96, alpha:1.0), forState: .highlighted)

 optionButton.setBackgroundColor(color: UIColor(red:0.96, green:0.96, blue:0.96, alpha:1.0), forState: .normal)


0

Швидкий 3:

extension UIButton {
    private func imageWithColor(color: UIColor) -> UIImage {
        let rect = CGRect(x:0.0,y:0.0,width: 1.0,height: 1.0)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()

        context!.setFillColor(color.cgColor)
        context!.fill(rect)

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image!
    }

    func setBackgroundColor(color: UIColor, forUIControlState state: UIControlState) {
        self.setBackgroundImage(imageWithColor(color: color), for: state)
    }
}

0

у Swift 5

Для тих, хто не хоче використовувати кольоровий фон для перебору обраного стану

Просто ви можете подолати проблему, використовуючи #Selector & if оператор, щоб легко змінити кольори UIButton для кожного стану окремо

Наприклад:

    override func viewDidLoad() {
    super.viewDidLoad()
    self.myButtonOutlet.backgroundColor = UIColor.white  //to reset the button color to its original color ( optionally )
}

@IBOutlet weak var myButtonOutlet: UIButton!{
    didSet{  // Button selector and image here
        self.myButtonOutlet.setImage(UIImage(systemName: ""), for: UIControl.State.normal)

        self.myButtonOutlet.setImage(UIImage(systemName: "checkmark"), for: UIControl.State.selected)



        self.myButtonOutlet.addTarget(self, action: #selector(tappedButton), for: UIControl.Event.touchUpInside)
    }
}

@objc func tappedButton() {  // Colors selection is here
    if self.myButtonOutlet.isSelected == true {

        self.myButtonOutlet.isSelected = false
        self.myButtonOutlet.backgroundColor = UIColor.white         
    } else {
        self.myButtonOutlet.isSelected = true

        self.myButtonOutlet.backgroundColor = UIColor.black
        self.myButtonOutlet.tintColor00 = UIColor.white

    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.