Usando a cor Tint em UIImageView

118

Eu tenho minha própria subclasse de UIButton. Eu adiciono UIImageViewe adiciono uma imagem. Gostaria de pintar sobre a imagem com um tom de cor, mas não funciona.

Até agora eu tenho:

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

e na seleção:

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

O que eu fiz errado? (A cor da imagem sempre permanece a mesma do que era originalmente.)

Marko Zadravec
fonte
você consegue ao setTintColorcriar o iconView ?
Himanshu Joshi
1
você quer dizer após self.iconView = [UIImageView alloc] ...? Sim, posso, mas não funciona.
Marko Zadravec
Use CGContext então. Pode ser que você possa encontrar sua resposta aqui stackoverflow.com/a/19275079/1790571
Himanshu Joshi
Sim, eu vejo esta postagem, mas realmente não entendo por que meu código não funciona. Usar a cor da tonalidade é um caminho muito mais limpo.
Marko Zadravec

Respostas:

237

Em vez deste código:

[image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

Você devia ter:

image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

Use isso no Swift 4.1

image = UIImage(named: "name")!.withRenderingMode(.alwaysTemplate)
Marko Zadravec
fonte
9
Não é um erro estúpido, mas um detalhe muito importante. Obrigado por postar isso. Você acabou de me economizar muito tempo. (erro de digitação corrigido)
Alex Zavatone de
47
Você pode selecionar a imagem em ativos e selecionar no modo de renderização padrão do painel direito
Nikolay Shubenkov,
Excelente! Mas como você volta para a imagem original sem cor?
Marsman
Se você quiser obter uma imagem não tingida, pode: armazenar uma imagem tingida em uma variável diferente: UIImage image2 = [image imageWithR ....] ou pode carregar a imagem do arquivo novamente: image = [UIImage imageNamed: @ "mais" ];
Marko Zadravec
89

Você também pode apenas definir isso em seu ativo. Certifique-se de que sua imagem contém todos os pixels brancos + transparente. insira a descrição da imagem aqui

StackUnderflow
fonte
6
Eu fiz tudo isso, mas por algum motivo o tintColor não funciona para mim. Alguma ideia do que mais eu poderia tentar?
Banana de
1
Que tipo de formato de imagem você está usando? E a imagem é toda branca + alfa?
StackUnderflow
3
Estranhamente, nas minhas primeiras execuções, apenas 2/3 das imagens adquiriram a cor da tonalidade. Após limpar e construir todas as imagens pegaram a tonalidade.
MathewS
Talvez você pudesse relatar isso para a Apple?
StackUnderflow de
11
@Banana, este é um problema conhecido das imagens que não usam a cor da tonalidade. Eu havia relatado isso para a Apple um tempo atrás e eles marcaram como uma duplicata, então eles definitivamente sabem sobre isso. A solução alternativa é não definir seu UIImageView como uma imagem no Storyboard. Portanto, basta ter um UIImageView em branco e configurá-lo no viewDidLoad (ou em outro lugar) e você verá o tintColor na imagem.
Mark Moeykens
38

(Não é possível editar a postagem @Zhaolong Zhong)

No swift 3.0 , você pode fazer:

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

yourImageView.image = image

yourImageView.tintColor = UIColor.blue
odemolliens
fonte
19

No swift 2.0+, você pode fazer:

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

yourImageView.image = image

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

Versão Swift: 5.2

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

Objetivo C

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

Ou

Você também pode simplesmente definir isso em seu ativo.

insira a descrição da imagem aqui

Nischal Hada
fonte
7

Um passo adiante. Esta é uma subclasse drop-in de UIImageView. (Não é a solução exata para a pergunta original.) Use no Interface Builder definindo o nome da classe como TintedImageView. Atualizações em tempo real dentro do designer conforme a tonalidade muda.

(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
fonte
2
não funciona, mas modifica a função configurar para: self.image = self.image? .withRenderingMode (UIImageRenderingMode.alwaysTemplate) let color = super.tintColor super.tintColor = UIColor.clear super.tintColor = color
lolo_house
5

Faça o imageView

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

Faça a imagem

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

Ligue-os juntos

    imageView?.image = image

Exibir

view.addSubview(imageView)
Gary Davies
fonte
1

tudo o que foi dito está correto. minha contribuição Se você não pode / não deseja aplicar a todos UiImageView, OU para eficiência, você precisa renderizar UMA VEZ (ou exemplo para células de tableviews)

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
    }

E defina para todos os elementos da interface do usuário este UIImage.

ingconti
fonte
1

A resposta de @odemolliens deve funcionar.

Mas se você ainda estiver tendo problemas, certifique-se de que a cor de matiz que você está aplicando ao UIImageView é diferente daquela definida no Interface Builder.

rockdaswift
fonte