Menggunakan warna Tint di UIImageView

118

Saya memiliki subkelas saya sendiri dari UIButton. Saya menambahkannya UIImageViewdan menambahkan gambar. Saya ingin mengecatnya di atas gambar dengan warna tint tetapi tidak berhasil.

Sejauh ini saya memiliki:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {

        self.backgroundColor = [UIColor clearColor];
        self.clipsToBounds = YES;

        self.circleView = [[UIView alloc]init];
        self.circleView.backgroundColor = [UIColor whiteColor];
        self.circleView.layer.borderColor = [[Color getGraySeparatorColor]CGColor];
        self.circleView.layer.borderWidth = 1;
        self.circleView.userInteractionEnabled = NO;
        self.circleView.translatesAutoresizingMaskIntoConstraints = NO;
        [self addSubview:self.circleView];

        self.iconView = [[UIImageView alloc]init];
        [self.iconView setContentMode:UIViewContentModeScaleAspectFit];
        UIImage * image = [UIImage imageNamed:@"more"];
        [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
        self.iconView.image = image;
        self.iconView.translatesAutoresizingMaskIntoConstraints = NO;
        [self.circleView addSubview:self.iconView];
        ...

dan dalam seleksi:

- (void) setSelected:(BOOL)selected
{
    if (selected) {
        [self.iconView setTintColor:[UIColor redColor]];
        [self.circleView setTintColor:[UIColor redColor]];
    }
    else{
        [self.iconView setTintColor:[UIColor blueColor]];
        [self.circleView setTintColor:[UIColor blueColor]];
    }  
}

Apa kesalahan yang telah aku perbuat? (Warna gambar selalu tetap sama seperti aslinya.)

Marko Zadravec
sumber
apakah Anda dapat melakukannya setTintColorsaat membuat iconView ?
Himanshu Joshi
1
maksud Anda setelah self.iconView = [UIImageView alokasi] ...? Ya saya bisa, tapi tidak berhasil.
Marko Zadravec
Gunakan CGContext lalu. Mungkin Anda dapat menemukan jawaban Anda di sini stackoverflow.com/a/19275079/1790571
Himanshu Joshi
Ya, saya melihat posting ini tetapi saya benar-benar tidak mengerti mengapa kode saya tidak berfungsi. Menggunakan warna tint jauh lebih bersih.
Marko Zadravec

Jawaban:

237

Alih-alih kode ini:

[image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

Kamu harus punya:

image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

Gunakan ini di Swift 4.1

image = UIImage(named: "name")!.withRenderingMode(.alwaysTemplate)
Marko Zadravec
sumber
9
Bukan kesalahan bodoh, tapi detail yang sangat penting. Terima kasih telah memposting ini. Anda baru saja menghemat banyak waktu saya. (dikoreksi salah ketik)
Alex Zavatone
47
Anda dapat memilih gambar dalam aset dan memilih dalam mode rendering default panel kanan
Nikolay Shubenkov
Luar biasa! Tetapi bagaimana Anda kembali ke gambar asli yang tidak diwarnai?
Marsman
Jika Anda ingin mendapatkan gambar tanpa warna, Anda dapat: menyimpan gambar berwarna dalam variabel berbeda: UIImage image2 = [image imageWithR ....], atau Anda dapat memuat gambar dari file lagi: image = [UIImage imageNamed: @ "more" ];
Marko Zadravec
89

Anda juga dapat menyetelnya di aset Anda. Pastikan gambar Anda berisi semua piksel putih + transparan. masukkan deskripsi gambar di sini

StackUnderflow
sumber
6
Saya melakukan semua ini, tetapi untuk beberapa alasan tintColor tidak berfungsi untuk saya. Tahu apa lagi yang bisa saya coba?
Pisang
1
Jenis format gambar apa yang Anda gunakan? Dan apakah gambar semuanya putih + alfa?
StackUnderflow
3
Anehnya, pada beberapa percobaan pertama saya, hanya 2/3 gambar yang mengambil warna tint. Setelah membersihkan dan membangun semua gambar mengambil warna tersebut.
MathewS
Mungkin Anda bisa melaporkannya ke Apple?
StackUnderflow
11
@ Pisang, ini adalah masalah umum tentang gambar yang tidak menggunakan warna tint. Saya telah melaporkannya ke Apple beberapa waktu yang lalu dan mereka menandainya sebagai duplikat sehingga mereka pasti mengetahuinya. Solusinya adalah tidak menyetel UIImageView Anda ke gambar di Storyboard. Jadi, cukup buat UIImageView kosong lalu setel di viewDidLoad (atau di tempat lain) dan Anda akan melihat tintColor pada gambar.
Mark Moeykens
38

(Tidak dapat mengedit postingan @Zhaolong Zhong)

Di swift 3.0 , Anda dapat melakukan:

let image = UIImage(named: "your_image_name")!.withRenderingMode(.alwaysTemplate)

yourImageView.image = image

yourImageView.tintColor = UIColor.blue
odemolliens
sumber
19

Di 2.0+ cepat, Anda dapat melakukan:

let image = UIImage(named: "your_image_name")!.imageWithRenderingMode(.AlwaysTemplate)

yourImageView.image = image

yourImageView.tintColor = UIColor.blueColor()
Zhaolong Zhong
sumber
11

Versi Swift: 5.2.0

let tintableImage = UIImage(named: "myImage")?.withRenderingMode(.alwaysTemplate)
imageView.image = tintableImage
imageView.tintColor = UIColor.red

Tujuan C

self.imgView.image = [self.imgView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[self.imgView setTintColor:[UIColor darkGrayColor]];

Atau

Anda juga dapat menyetelnya di aset Anda.

masukkan deskripsi gambar di sini

Nischal Hada
sumber
7

Satu langkah kedepan. Ini adalah subclass drop-in dari UIImageView. (Bukan solusi tepat untuk pertanyaan awal.) Gunakan di Interface Builder dengan menyetel nama kelas ke TintedImageView. Pembaruan secara real-time di dalam desainer saat warna tint berubah.

(Swift 3.1, Xcode 8.3)

import UIKit

@IBDesignable class TintedImageView: UIImageView {
    override func prepareForInterfaceBuilder() {
        self.configure()
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        self.configure()
    }

    @IBInspectable override var tintColor: UIColor! {
        didSet {
            self.configure()
        }
    }

    private func configure() {
        self.image = self.image?.withRenderingMode(UIImageRenderingMode.alwaysTemplate)
    }
}
Daniel
sumber
2
tidak berfungsi, tetapi memodifikasi func configure menjadi: self.image = self.image? .withRenderingMode (UIImageRenderingMode.alwaysTemplate) biarkan color = super.tintColor super.tintColor = UIColor.clear super.tintColor = color
lolo_house
5

Buat imageView tersebut

    let imageView = UIImageView(frame: frame!)
    imageView.contentMode = .ScaleAspectFit
    imageView.tintColor = tintColor

Buat gambarnya

    let mainBundle = NSBundle.mainBundle()
    var image = UIImage(named: filename!, inBundle: mainBundle, compatibleWithTraitCollection: nil)
    image = image?.imageWithRenderingMode(.AlwaysTemplate)

Hubungkan mereka

    imageView?.image = image

Tampilkan itu

view.addSubview(imageView)
Gary Davies
sumber
1

semua yang dikatakan benar. kontribusi saya Jika Anda tidak dapat / tidak ingin menerapkan ke setiap UiImageView, ATAU untuk efisiensi Anda perlu merender SEKALI (atau contoh untuk sel tampilan tabel)

func tint(with color: UIColor) -> UIImage {
        var image = withRenderingMode(.alwaysTemplate)
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        color.set()

        image.draw(in: CGRect(origin: .zero, size: size))
        image = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }

Dan atur ke semua elemen UI UIImage ini.

ingconti
sumber
1

Jawaban @odemolliens seharusnya berfungsi.

Namun jika Anda masih mengalami masalah, pastikan bahwa warna tint yang Anda terapkan ke UIImageView berbeda dari yang ditentukan dalam Interface Builder.

rockdaswift
sumber