Как изменить цвет фона UIButton, пока он подсвечен?

236

В какой-то момент в моем приложении у меня есть выделение UIButton(например, когда пользователь держит палец на кнопке), и мне нужно изменить цвет фона, когда кнопка подсвечена (так, пока палец пользователя все еще находится на кнопке) ,

Я попробовал следующее:

_button.backgroundColor = [UIColor redColor];

Но это не работает. Цвет остается прежним. Я попробовал тот же кусок кода, когда кнопка не выделена, и она работает нормально. Я также попытался позвонить -setNeedsDisplayпосле изменения цвета, это не имело никакого эффекта.

Как заставить кнопку изменить цвет фона?

MartinMoizard
источник
Проверьте этот пост что-
тоaboutios.wordpress.com/2016/02/

Ответы:

411

Вы можете переопределить UIButton«S setHighlightedметод.

Objective-C

- (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, как мне настроить кнопку для изменения цвета фона при выделении или нажатии? Буду ли я создавать подкласс setHIghlighted в COnversionViewController?
Beanno1116
Итак, есть одна проблема с этим ответом, которую я нашел. Если вы хотите, чтобы тот же цвет был доступен при выборе кнопки, тогда setHighlighted вызывается после setSelected и, таким образом, переопределяет любой выбранный вами стиль. Решение выше может быть лучше, если вы также хотите выбрать кнопку
HaloZero
3
@YakivKovalskiy Если вы используете подкласс, вы можете добавить два свойства UIColor, например, normalBackground и selectedBackground, а затем назначить self.backgroundColor = normalBackground или selectedBackground соответственно. Не забудьте добавить метод init для простоты использования, например, initWithBackground: selectedBackground:
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 в buttonHighlight: список событий, и он будет работать всегда.
Евгений Бодунов
Второй вариант - лучший, который я нашел до сих пор. Я думаю, однако, что раскадровки имеют свои преимущества в этом случае!
Джек Соломон
Ответ Томаса лучше, и это то, что я тоже использую
Ван Ду Тран
26
Если вы используете layer.cornerRadiusопцию №2 и переключаетесь clipsToBoundsна нее, вам нужно обязательно установить значение true, чтобы углы изображения также были закруглены.
Небо
3
Если кто-то заходит и нуждается в ответе в Swift: stackoverflow.com/questions/26600980/…
зиме
94

Нет необходимости переопределять highlightedкак вычисляемое свойство. Вы можете использовать наблюдатель свойства, чтобы вызвать изменение цвета фона:

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

Swift 4

override open var isHighlighted: Bool {
    didSet {
        backgroundColor = isHighlighted ? UIColor.lightGray : UIColor.white
    }
}
Алексей Мяликс
источник
1
Я никогда не использовал такую ​​функциональность. Можете ли вы объяснить, куда это идет? Это функция IBAction buttonPress или viewDidLoad?
Дэйв Г
Что если у меня несколько кнопок UIB разных цветов?
Славчо
6
@Dave G, вы создаете новый подкласс UIButton, нажав File>New>File>Cocoa Touch Classи установив его в subclass of UIButton. Назовите файл для ex CustomButton, который станет и именем файла, и именем класса. Внутри этого файла поместите override var highlightedкод, показанный выше. Последний шаг, установите UIButton в Интерфейсном Разработчике, чтобы использовать этот CustomButtonподкласс, перейдя на страницу свойств, где он говорит «Пользовательский класс» и имеет раскрывающийся список. Он будет говорить «UIButton» серыми буквами. В раскрывающемся списке должна отображаться CustomButton. Выберите это, и кнопка теперь находится в подклассе.
Джеймс Туми
Почему никто не упомянул, что сеттер вызывается только при нажатии на кнопку, а не во время первоначального макета! Поэтому по умолчанию цвет отсутствует, пока вы не нажмете кнопку.
Дмитрий
Поэтому, чтобы заставить его работать, вам также нужно явно вызвать isHighlighted = falseгде-то в начале (например, при инициализации).
Дмитрий
50

Удобное универсальное расширение в 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 вы можете переопределить метод доступа выделенного (или выбранного) свойства вместо переопределения метода setHighlighted

override var highlighted: Bool {
        get {
            return super.highlighted
        }
        set {
            if newValue {
                backgroundColor = UIColor.blackColor()
            }
            else {
                backgroundColor = UIColor.whiteColor()
            }
            super.highlighted = newValue
        }
    }
Джейк Холл
источник
Это полностью работает, но я запутался, как вы смогли это выяснить? Насколько я могу судить, параметров нет в документации или UIButton.h.
Симидзу
1
Это быстрый синтаксис, который имитирует поведение переопределения setHightlighted в цели c. См. Документацию по Computed Properties здесь: developer.apple.com/library/ios/documentation/Swift/Conceptual/…
Джейк Холл,
11
В Swift вы могли бы использовать didSet
Dam
1
Я добавил пример с наблюдателем свойства: stackoverflow.com/a/29186375/195173 .
Алексей Мяликс
Я думаю, что @shimizu спрашивал, откуда вы узнали, что highlightedэто собственность на UIButton. Ответ в том, что это свойство UIControl, от которого наследуется UIButton.
Адам Джонс
25

Переопределить выделенную переменную. Добавление @IBInspectableзаставляет вас редактировать подсвеченный backgroundColor в раскадровке, что тоже изящно.

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 это переопределит isHighlighted во всех кнопках в вашем приложении, что, на мой взгляд, не является хорошим решением. Я пойду с ответом Тимура.
Усама бен Аттик
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, называемого selectedBackgroundColor. Подобно подклассу, не требуя подкласса.

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
                }
            }
        }
    }
}

Надеюсь, это поможет.

Fostah
источник
1
Для swift 2.0 вам нужно обновить вызов objc_setAssociatedObject, чтобы использовать перечисление: objc_setAssociatedObject (self, & NormalBackgroundColorKey, newValue, .OBJC_ASSOCIATION_RETAIN)
Эли Берк,
Определенно лучший способ в Swift, если вы хотите сохранить все это в раскадровке.
davidethell
1
Я предпочитаю использовать подкласс, а не расширение, так как это повлияет на все приложение
Хоссам Гариб,
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.

OLD:

Используйте помощники ниже, чтобы создать изображение размером 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.

ma11hew28
источник
4

Попробуй это !!!!

Для события TouchedDown установите один цвет, а для 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 и сделать хороший forState.

colourButton.h

#import <UIKit/UIKit.h>

@interface colourButton : UIButton

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

@end

colourButton.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)
    }

}

Swift 5 , спасибо @Maverick

dengST30
источник
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достаточно ли это для вас.

Сиби
источник
Я попытался поиграть с шоу Touch, когда Highlighted, но это не помогло. Я не хочу использовать 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 и Objective-C.

ВАЖНЫЙ

Я также написал сообщение в блоге с дополнительной информацией.

Gabriel.Massana
источник
2
class CustomButton: UIButton {

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

}
evya
источник
1

Попробуй tintColor:

_button.tintColor = [UIColor redColor];
jjv360
источник
Вы уверены, что это связано в 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

если вы не хотите переопределять, просто установите два действия touchDown touchUpInside

Роман Бамбура
источник
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)
    }
}
Elita
источник
0

в Свифте 5

Для тех, кто не хочет использовать цветной фон, чтобы побить выбранное состояние

Просто вы можете справиться с этой проблемой с помощью оператора #Selector & if, чтобы легко и просто изменять цвета кнопок UIB для каждого состояния.

Например:

    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

    }
}
Let.Simoo
источник