Color Tint Gambar UIButton

294

Saya perhatikan bahwa ketika saya menempatkan putih atau hitam UIImageke dalam UISegmentedControlitu secara otomatis warna topeng itu agar sesuai dengan warna kontrol tersegmentasi. Saya pikir ini sangat keren, dan bertanya-tanya apakah saya bisa melakukan ini di tempat lain juga. Sebagai contoh, saya memiliki banyak tombol yang memiliki bentuk seragam tetapi warnanya bervariasi. Alih-alih membuat PNG untuk setiap tombol, bisakah saya menggunakan masking warna ini untuk menggunakan gambar yang sama untuk mereka semua tetapi kemudian mengatur warna tint atau sesuatu untuk mengubah warna sebenarnya?

Logan Shire
sumber
Bisakah Anda memposting gambar yang ingin Anda gunakan dan juga gambar untuk hasil yang diinginkan?
Pratyusha Terli
ini melakukan hal yang sama dari interface builder stackoverflow.com/a/25179217/2051381
Chuy47

Jawaban:

619

Pada iOS 7, ada metode baru UIImageuntuk menentukan mode rendering. Menggunakan mode rendering UIImageRenderingModeAlwaysTemplateakan memungkinkan warna gambar dikontrol oleh warna warna tombol.

Objektif-C

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

Cepat

let button = UIButton(type: .custom)
let image = UIImage(named: "image_name")?.withRenderingMode(.alwaysTemplate)
button.setImage(image, for: .normal)
button.tintColor = UIColor.red
Ric Santos
sumber
14
Saya pikir lebih baik menggunakan button.imageView.tintColor
M.Othman
3
@ M.Othman hanya bekerja untuk saya ketika saya menggunakan button.tintColor dan bukan button.imageview.tintColor
pnizzle
32
Hanya ingat untuk mengatur mode render gambar pada gambar dalam xcassets per @hashier
Dean
23
Membuat UIButton dengan tipe UIButtonTypeSystem akan secara otomatis menghormati tintColor yang Anda atur.
carloshwa
4
Jika Anda tintColorterlalu gelap, pastikan adjustsImageWhenHighlightedTIDAK. (Atau dalam IB: "Gambar yang Disorot Menyoroti" tidak dicentang.)
Jason Moore
225

Seperti yang sudah disebutkan Ric di postingannya, Anda dapat mengatur mode render dalam kode, Anda juga dapat melakukan ini secara langsung di katalog gambar, lihat gambar terlampir di bawah ini. Cukup atur Render AskeTemplate Image

masukkan deskripsi gambar di sini

Peringatan Saya punya masalah dengan iOS 7 dan pendekatan ini. Jadi jika Anda menggunakan iOS 7 juga Anda mungkin ingin melakukannya dalam kode juga untuk memastikan, seperti dijelaskan di sini .

hashier
sumber
1
Sebagai catatan tambahan, file gambar harus hitam dan transparan (bukan b & w)
Axel Guilmin
6
@AxelGuilmin tidak juga. Gambar Anda bisa warna apa saja yang Anda inginkan dan transparan. Setiap warna yang berbeda dari transparan akan dikonversi ke warna generik dan kemudian akan diwarnai dengan warna hitam secara default.
Alejandro Iván
90

Tombol Kustom muncul dalam warna gambar masing-masing. Mengatur jenis tombol ke "System" di storyboard (atau ke UIButtonTypeSystemdalam kode), akan membuat gambar tombol dengan warna warna default.

Jenis Tombol, Sistem Membuat Ikon berwarna

(diuji pada iOS9, Xcode 7.3)

auco
sumber
2
Yang dapat dihindari dengan metode alwaysTemplate dan tintColor yang disarankan di sini. Dengan memanfaatkan tombol .system, Anda mendapatkan perubahan warna dengan menyentuh ketukan.
Chris Prince
44

Anda harus mengatur mode rendering gambar UIImageRenderingModeAlwaysTemplateagar dapat tintColormempengaruhi UIImage. Inilah solusinya di 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
Nick Wargnier
sumber
28

Jika Anda memiliki tombol khusus dengan gambar latar belakang. Anda dapat mengatur warna warna tombol Anda dan menimpa gambar dengan mengikuti.

Dalam aset pilih latar belakang tombol yang ingin Anda atur warna warna.

Pada pemeriksa atribut gambar atur nilai render ke "Template Image"

masukkan deskripsi gambar di sini

Sekarang setiap kali Anda mengatur button.tintColor = UIColor.redtombol Anda akan ditampilkan dalam warna merah.

Ilker Baltaci
sumber
jika Anda di sini, Anda dapat membuka tautan ini: useyourloaf.com/blog/styling-buttons-using-the-asset-catalog dan pergi ke templat gambar (untuk dijadikan penjelasan)
cspam
Ini adalah solusi yang lebih baik karena mengurangi kode dan cukup banyak melakukan hal yang sama dengan jawaban yang diterima.
DS.
Saya pikir ini harus menjadi yang benar. kode lebih sedikit dan mudah ditangani.
Umair_UAS
17

Di Swift Anda dapat melakukannya seperti:

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

Kemudian di viewDidLoad Anda

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

Dan untuk memodifikasi warnanya

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

EDIT Xcode 8 Sekarang Anda bisa juga hanya modus render gambar di .xcassets Anda untuk Template Gambar dan kemudian Anda tidak perlu secara khusus menyatakan hal itu dalam var exampleImagelagi

henrik-dmg
sumber
14

Tidak yakin persis apa yang Anda inginkan tetapi metode kategori ini akan menutupi UIImage dengan warna yang ditentukan sehingga Anda dapat memiliki satu gambar dan mengubah warnanya menjadi apa pun yang Anda inginkan.

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

Impor kategori ImageUtils dan lakukan sesuatu seperti ini ...

#import "ImageUtils.h"

...

UIImage *icon = [UIImage imageNamed:ICON_IMAGE];

UIImage *redIcon = [icon maskWithColor:UIColor.redColor];
UIImage *blueIcon = [icon maskWithColor:UIColor.blueColor];
Kirby Todd
sumber
3
Gunakan kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLastpadaCGBitmapContextCreate
Luis Ascorbe
4
Bagus, tetapi perlu di-tweak untuk grafis Retina ... Ketika saya menjalankan ini pada gambar Retina, ia mengembalikan saya yang bukan retina.
jowie
Untuk mendukung perangkat Retina Anda bisa menggunakan properti skala yang UIDevicekelas: CGFloat scale = [UIScreen mainScreen].scale; CGFloat width = self.size.width * scale; CGFloat height = self.size.height * scale;The scaleproperti ada sebagai iOS 4.0.
Philipp Frischmuth
Anda juga perlu menggunakan scalenilai saat UIImagedibuat:UIImage *coloredImage = [UIImage imageWithCGImage:cImage scale:scale orientation:self.imageOrientation];
Philipp Frischmuth
8

Swift 4 dengan customType:

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

Untuk 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);
Maciej
sumber
5

Swift 3 :

Solusi ini bisa nyaman jika Anda telah mengatur gambar Anda melalui pembangun antarmuka xCode. Pada dasarnya Anda memiliki satu ekstensi untuk mewarnai gambar:

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

Kemudian, Anda dapat menyiapkan ekstensi UIButton ini untuk mewarnai gambar untuk kondisi tertentu:

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

Pemakaian:

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

PS (berfungsi baik juga dalam sel tabel, Anda tidak perlu memanggil setNeedDisplay()metode, perubahan warna langsung karena ekstensi UIImage ..

Alessandro Ornano
sumber
3

Jika Anda ingin secara manual menyamarkan gambar Anda, berikut adalah kode yang diperbarui yang berfungsi dengan layar retina

- (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;
}
Josh Bernfeld
sumber
2

Kamu harus mencobanya

Setelah Mengatur Frame

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];

}
guptha
sumber
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)
Jad
sumber
1

Ubah gambar tombol atau tampilan gambar warna warna Swift:

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

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

Tidak satu pun di atas yang berfungsi untuk saya, karena warna dihapus setelah klik. Saya harus menggunakan

button.setImageTintColor(Palette.darkGray(), for: UIControlState())
Szymon Klimaszewski
sumber