260

アプリのある時点でハイライト表示されUIButton(たとえば、ユーザーがボタンに指を置いている場合)、ボタンがハイライト表示されている間に背景色を変更する必要があります (つまり、ユーザーの指がまだボタン上にある間)。 .

私は次のことを試しました:

_button.backgroundColor = [UIColor redColor];

しかし、それは機能していません。色はそのままです。ボタンが強調表示されていないときに同じコードを試してみましたが、正常に動作しました。色を変えてから呼び出してみ-setNeedsDisplayましたが、効果がありませんでした。

ボタンの背景色を強制的に変更するにはどうすればよいですか?

4

31 に答える 31

437

UIButtonsetHighlightedメソッドをオーバーライドできます。

Objective-C

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

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

スウィフト 3.0 およびスウィフト 4.1

override open var isHighlighted: Bool {
    didSet {
        backgroundColor = isHighlighted ? UIColor.black : UIColor.white
    }
}
于 2013-07-11T19:56:34.477 に答える
305

この種の解決策で解決できるかどうか、または一般的な開発環境に適合するかどうかはわかりませんが、最初に試みることは、 touchDown イベントのボタンの背景色を変更することです。

オプション1:

キャプチャするには 2 つのイベントが必要です。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];
于 2013-01-25T15:40:36.447 に答える
98

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
    }
}
于 2015-03-21T18:24:07.717 に答える
53

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

スイフト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)
    }
}
于 2014-11-23T22:55:16.127 に答える
25

よりコンパクトなソリューション(@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)
  }
}
于 2016-03-26T03:10:16.747 に答える
16

サブクラス化を行わない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)
于 2017-06-02T09:49:14.993 に答える
13

Swift 3+構文による UIButton 拡張機能:

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

于 2016-10-05T08:22:23.023 に答える
9

メソッドsetBackgroundColor:forStateを追加するこのカテゴリを使用できます。

https://github.com/damienromito/UIButton-setBackgroundColor-forState-

于 2015-01-22T16:00:25.387 に答える
6
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

于 2019-09-04T06:14:01.037 に答える
5

アップデート:

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は、Acani Utilities と呼ばれる私の Cocoa Touch Static Library のクラス プレフィックスです。AC は Acani、U は Utilities です。

于 2014-04-11T16:44:19.483 に答える
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
            }
        }
    }
}
于 2016-11-24T09:02:25.927 に答える
3

UIButton をサブクラス化して、素敵な forState を作成できます。

colorButton.h

#import <UIKit/UIKit.h>

@interface colourButton : UIButton

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

@end

colorButton.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

(これは一例です。問題があることはわかっています。ここにその一部を示します)

各 State の UIColor を格納するために NSMutableDictionay を使用しました。UIControlState は適切なストレートな Int ではないため、Key に対して厄介なテキスト変換を行う必要があります。その数のオブジェクトで配列を初期化し、状態をインデックスとして使用できる場合。

このため、選択されたボタンや無効なボタンなど、多くの人が問題を抱えています。さらにロジックが必要です。

別の問題は、同時に複数の色を設定しようとすると、ボタンで試したことはありませんが、これができる場合は機能しない可能性があります

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

私はこれが StoryBoard であると想定しています。init、initWithFrame はありませんので、必要に応じて追加してください。

于 2014-12-18T14:07:08.687 に答える
2

画像がある場合は、これを試してください:

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

showsTouchWhenHighlightedまたは、あなたにとって十分かどうかを確認してください。

于 2013-01-25T14:26:55.187 に答える
2

この問題を解決するために、状態を処理するカテゴリを作成しましたbackgroundColor: UIButtonsButtonBackgroundColor
-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 で簡単に使用できるようになります。

重要

詳細については、ブログ投稿も書きました。

于 2016-02-09T21:25:11.600 に答える
2

私は UIButton サブクラスSTAButtonをオープンソース化して、このギャップのある機能の穴を埋めました。MIT ライセンスの下で利用できます。iOS 7 以降で動作します (古い iOS バージョンではテストしていません)。

于 2015-05-27T00:27:27.640 に答える
1

試してみてくださいtintColor

_button.tintColor = [UIColor redColor];
于 2013-01-25T14:06:28.933 に答える
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)
于 2016-01-06T07:56:51.457 に答える
0

オーバーライドしない場合は、2 つのアクション touchDown touchUpInside を設定するだけです

于 2016-12-28T10:35:03.323 に答える