色合いUIButtonイメージ


294

白または黒UIImageをそこに配置するUISegmentedControlと、セグメント化されたコントロールの色合いに一致するように、自動的にカラーマスクされます。これは本当にかっこいいと思ったので、他の場所でもこれができるかと思いました。たとえば、私はボタンがたくさんあるのに、形は統一されていますが、色はさまざまです。各ボタンにPNGを作成する代わりに、このカラーマスキングを使用してすべてのボタンに同じ画像を使用できますが、色合いの色または何かを設定して実際の色を変更できますか?


使用したい画像や希望の画像を投稿して頂けますか?
Pratyusha Terli 2013年

これは、インターフェイスビルダーstackoverflow.com/a/25179217/2051381
Chuy47

回答:


619

iOS 7以降UIImage、レンダリングモードを指定する新しいメソッドがあります。レンダリングモードUIImageRenderingModeAlwaysTemplateを使用すると、画像の色をボタンの色合いで制御できます。

Objective-C

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *image = [[UIImage imageNamed:@"image_name"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[button setImage:image forState:UIControlStateNormal]; 
button.tintColor = [UIColor redColor];

迅速

let button = UIButton(type: .custom)
let image = UIImage(named: "image_name")?.withRenderingMode(.alwaysTemplate)
button.setImage(image, for: .normal)
button.tintColor = UIColor.red

14
button.imageView.tintColorを使用する方がよいと思います
M.Othman

3
@ M.Othmanは、button.tintColorを使用し、button.imageview.tintColorを使用しない場合にのみ機能します
pnizzle

32
@hashierのxcassetsで画像に画像レンダリングモードを設定することを忘れないでください
Dean

23
タイプUIButtonTypeSystemのUIButtonを作成すると、設定したtintColorが自動的に適用されます。
carloshwa 2015年

4
tintColor暗すぎる場合adjustsImageWhenHighlightedは、NOにしてください。(またはIBの場合:[強調表示された画像の調整]はオフになっています。)
Jason Moore

225

Ricが彼の投稿ですでに述べたように、コードでレンダリングモードを設定できます。これは、イメージカタログで直接行うこともできます。下の添付画像を参照してください。ただ、セットRender AsTemplate Image

ここに画像の説明を入力してください

警告私はiOS 7とこのアプローチに問題がありました。したがって、iOS 7も使用している場合は、こちらで説明さているように、コードでも確認することをお勧めします


1
補足として、画像ファイルは黒で透明でなければなりません(白黒ではありません)
Axel Guilmin

6
@AxelGuilminはそうではありません。画像は、好きな色で透明にすることができます。透明以外の色は一般的な色に変換され、デフォルトで黒色に着色されます。
AlejandroIván2016年

90

カスタムボタンはそれぞれの画像の色で表示されます。ストーリーボードで(またはUIButtonTypeSystemコードで)ボタンタイプを「システム」に設定すると、デフォルトの色合いでボタンの画像がレンダリングされます。

ボタン型システムは、色付きのアイコンをレンダリングします

(iOS9、Xcode 7.3でテスト済み)


2
これは、ここで提案されているalwaysTemplateメソッドとtintColorメソッドで回避できます。.systemボタンの利点は、タップするだけで色を変更できることです。
クリスプリンス

44

UIImageに影響を与えるには、画像のレンダリングモードをUIImageRenderingModeAlwaysTemplateに設定する必要がありますtintColor。これがSwiftのソリューションです:

let image = UIImage(named: "image-name")
let button = UIButton()
button.setImage(image?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate), forState: .Normal)
button.tintColor = UIColor.whiteColor()

SWIFT 4x

button.setImage(image.withRenderingMode(UIImage.RenderingMode.alwaysTemplate), for: .normal)
button.tintColor = UIColor.blue

28

背景画像付きのカスタムボタンがある場合。ボタンの濃淡色を設定し、次のように画像を上書きできます。

アセットで、ティントカラーを設定するボタンの背景を選択します。

画像の属性インスペクターで、「テンプレート画像」としてレンダリングの値を設定します

ここに画像の説明を入力してください

これで、設定button.tintColor = UIColor.redするたびにボタンが赤で表示されます。


ここにいる場合は、このリンクにアクセスできます:useyourloaf.com/blog/styling-buttons-using-the-asset-catalogおよびテンプレート画像に移動します(説明として使用)
cspam

これはコードを減らし、受け入れられた回答とほとんど同じことをするので、より良いソリューションです。
DS。

これは正解だと思います。コードが少なく、扱いやすい。
Umair_UAS

17

Swiftではそれを次のように行うことができます:

var exampleImage = UIImage(named: "ExampleImage.png")?.imageWithRenderingMode(.AlwaysTemplate)

次に、viewDidLoad

exampleButtonOutlet.setImage(exampleImage, forState: UIControlState.Normal)

そして、色を変更するには

exampleButtonOutlet.tintColor = UIColor(red: 1, green: 0, blue: 0, alpha: 1) //your color

Xcode 8の編集 これで、.xcassets内の画像のレンダリングモードだけをテンプレート画像にできるようになりました。var exampleImageこれで、特別にそれを宣言する必要がなくなりました。


14

正確に何が必要かはわかりませんが、このカテゴリメソッドは指定された色でUIImageをマスクするため、単一の画像を作成してその色を好きなように変更できます。

ImageUtils.h

- (UIImage *) maskWithColor:(UIColor *)color;

ImageUtils.m

-(UIImage *) maskWithColor:(UIColor *)color 
{
    CGImageRef maskImage = self.CGImage;
    CGFloat width = self.size.width;
    CGFloat height = self.size.height;
    CGRect bounds = CGRectMake(0,0,width,height);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef bitmapContext = CGBitmapContextCreate(NULL, width, height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
    CGContextClipToMask(bitmapContext, bounds, maskImage);
    CGContextSetFillColorWithColor(bitmapContext, color.CGColor);    
    CGContextFillRect(bitmapContext, bounds);

    CGImageRef cImage = CGBitmapContextCreateImage(bitmapContext);
    UIImage *coloredImage = [UIImage imageWithCGImage:cImage];

    CGContextRelease(bitmapContext);
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(cImage);

    return coloredImage;    
}

ImageUtilsカテゴリをインポートして、次のようにします...

#import "ImageUtils.h"

...

UIImage *icon = [UIImage imageNamed:ICON_IMAGE];

UIImage *redIcon = [icon maskWithColor:UIColor.redColor];
UIImage *blueIcon = [icon maskWithColor:UIColor.blueColor];

3
使用kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast上のCGBitmapContextCreate
ルイス・Ascorbe

4
いいですが、Retinaグラフィックを微調整する必要があります...これをRetinaイメージで実行すると、Retina以外の画像が返されます。
ジョーイ14

Retinaデバイスをサポートするには、UIDeviceクラスのscaleプロパティを使用できます。CGFloat scale = [UIScreen mainScreen].scale; CGFloat width = self.size.width * scale; CGFloat height = self.size.height * scale;このscaleプロパティはiOS 4.0以降に存在します。
Philipp Frischmuth、2015年

また、使用する必要があるscale時に値をUIImage作成されます:UIImage *coloredImage = [UIImage imageWithCGImage:cImage scale:scale orientation:self.imageOrientation];
フィリップFrischmuth

8

customTypeを使用したSwift 4:

let button = UIButton(frame: aRectHere)
    let buttonImage = UIImage(named: "imageName")
    button.setImage(buttonImage?.withRenderingMode(.alwaysTemplate), for: .normal)
    button.tintColor = .white

5

Xamarin.iOS(C#)の場合:

        UIButton messagesButton = new UIButton(UIButtonType.Custom);
        UIImage icon = UIImage.FromBundle("Images/icon.png");
        messagesButton.SetImage(icon.ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate), UIControlState.Normal);
        messagesButton.TintColor = UIColor.White;
        messagesButton.Frame = new RectangleF(0, 0, 25, 25);

5

スウィフト3

このソリューションは、xCodeインターフェースビルダーを介して画像をすでに設定している場合に快適です。基本的に、画像に色を付ける拡張機能が1つあります。

extension UIImage {
    public func image(withTintColor color: UIColor) -> UIImage{
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        let context: CGContext = UIGraphicsGetCurrentContext()!
        context.translateBy(x: 0, y: self.size.height)
        context.scaleBy(x: 1.0, y: -1.0)
        context.setBlendMode(CGBlendMode.normal)
        let rect: CGRect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
        context.clip(to: rect, mask: self.cgImage!)
        color.setFill()
        context.fill(rect)
        let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return newImage
    }
}

次に、このUIButton拡張機能を準備して、特定の状態の画像に色を付けることができます

extension UIButton {
    func imageWith(color:UIColor, for: UIControlState) {
        if let imageForState = self.image(for: state) {
            self.image(for: .normal)?.withRenderingMode(.alwaysTemplate)
            let colorizedImage = imageForState.image(withTintColor: color)
            self.setImage(colorizedImage, for: state)
        }
    }
}

使用法:

myButton.imageWith(.red, for: .normal)

PS(テーブルセルでも機能します。setNeedDisplay()メソッドを呼び出す必要はありません。UIImage拡張により、色の変更はすぐに反映されます。


3

画像を手動でマスクしたい場合は、網膜画面で動作する更新されたコードを次に示します

- (UIImage *)maskWithColor:(UIColor *)color
{
    CGImageRef maskImage = self.CGImage;
    CGFloat width = self.size.width * self.scale;
    CGFloat height = self.size.height * self.scale;
    CGRect bounds = CGRectMake(0,0,width,height);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef bitmapContext = CGBitmapContextCreate(NULL, width, height, 8, 0, colorSpace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast);
    CGContextClipToMask(bitmapContext, bounds, maskImage);
    CGContextSetFillColorWithColor(bitmapContext, color.CGColor);
    CGContextFillRect(bitmapContext, bounds);

    CGImageRef cImage = CGBitmapContextCreateImage(bitmapContext);
    UIImage *coloredImage = [UIImage imageWithCGImage:cImage scale:self.scale orientation:self.imageOrientation];

    CGContextRelease(bitmapContext);
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(cImage);

    return coloredImage;
}

2

試してみてください

フレームを設定した後

NSArray *arr10 =[NSArray arrayWithObjects:btn1,btn2,nil];
for(UIButton *btn10 in arr10)
{
CAGradientLayer *btnGradient2 = [CAGradientLayer layer];
btnGradient2.frame = btn10.bounds;

btnGradient2.colors = [NSArray arrayWithObjects:
                       (id)[[UIColor colorWithRed:151.0/255.0f green:206.0/255.5 blue:99.0/255.0 alpha:1] CGColor],
                       (id)[[UIColor colorWithRed:126.0/255.0f green:192.0/255.5 blue:65.0/255.0 alpha:1]CGColor],
                       nil];
[btn10.layer insertSublayer:btnGradient2 atIndex:0];

}

2

Swift 3.0

    let image = UIImage(named:"NoConnection")!

 warningButton = UIButton(type: .system)        
    warningButton.setImage(image, for: .normal)
    warningButton.tintColor = UIColor.lightText
    warningButton.frame = CGRect(origin: CGPoint(x:-100,y:0), size: CGSize(width: 59, height: 56))

    self.addSubview(warningButton)

1

ボタン画像または画像ビューのティントカラーの変更Swift:

btn.imageView?.image = btn.imageView?.image?.withRenderingMode(.alwaysTemplate)

btn.imageView?.tintColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)

-1

クリックすると色合いがクリアされたため、上記のどれもうまくいきませんでした。私は使用しなければなりませんでした

button.setImageTintColor(Palette.darkGray(), for: UIControlState())
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.