Verwenden der Farbtonfarbe in UIImageView

118

Ich habe meine eigene Unterklasse von UIButton. Ich füge UIImageViewes hinzu und füge ein Bild hinzu. Ich würde es gerne mit einer Tönungsfarbe über das Bild malen, aber es funktioniert nicht.

Bisher habe ich:

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

und bei Auswahl:

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

Was habe ich falsch gemacht? (Die Farbe des Bildes bleibt immer dieselbe wie ursprünglich.)

Marko Zadravec
quelle
Können Sie dies setTintColorbeim Erstellen der iconView tun ?
Himanshu Joshi
1
meinst du nach self.iconView = [UIImageView alloc] ...? Ja, ich kann, aber es funktioniert nicht.
Marko Zadravec
Verwenden Sie dann CGContext. Vielleicht
Himanshu Joshi
Ja, ich sehe diesen Beitrag, aber ich verstehe wirklich nicht, warum mein Code nicht funktioniert. Die Verwendung von Farbton ist ein viel saubererer Weg.
Marko Zadravec

Antworten:

237

Anstelle dieses Codes:

[image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

du solltest haben:

image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

Verwenden Sie dies in Swift 4.1

image = UIImage(named: "name")!.withRenderingMode(.alwaysTemplate)
Marko Zadravec
quelle
9
Kein dummer Fehler, aber ein sehr wichtiges Detail. Vielen Dank für die Veröffentlichung. Du hast mir gerade viel Zeit gespart. (Tippfehler korrigiert)
Alex Zavatone
47
Sie können Bild in Assets auswählen und im rechten Bereich den Standard-Rendering-Modus auswählen
Nikolay Shubenkov
Ausgezeichnet! Aber wie kehren Sie zum ungetönten Originalbild zurück?
Marsman
Wenn Sie ein nicht getöntes Bild erhalten möchten, können Sie: getöntes Bild in einer anderen Variablen speichern: UIImage image2 = [image imageWithR ....], oder Sie können das Bild erneut aus der Datei laden: image = [UIImage imageNamed: @ "more" ];
Marko Zadravec
89

Sie können dies auch einfach für Ihr Asset festlegen. Stellen Sie sicher, dass Ihr Bild alle weißen Pixel + transparent enthält. Geben Sie hier die Bildbeschreibung ein

StackUnderflow
quelle
6
Ich habe das alles gemacht, aber aus irgendeinem Grund funktioniert die tintColor bei mir nicht. Irgendeine Idee, was ich sonst noch versuchen könnte?
Banane
1
Welche Art von Bildformat verwenden Sie? Und ist das Bild ganz weiß + alpha?
StackUnderflow
3
Seltsamerweise nahmen bei meinen ersten Läufen nur 2/3 Bilder die Farbtonfarbe auf. Nach dem Reinigen und Bauen nahmen alle Bilder den Farbton auf.
MathewS
Vielleicht könnten Sie das Apple melden?
StackUnderflow
11
@ Banana, dies ist ein bekanntes Problem bei Bildern, die nicht die Farbtonfarbe verwenden. Ich hatte es vor einiger Zeit Apple gemeldet und sie haben es als Duplikat markiert, damit sie definitiv davon wissen. Die Problemumgehung besteht darin, UIImageView nicht auf ein Bild im Storyboard festzulegen. Haben Sie also einfach eine leere UIImageView und setzen Sie sie dann in viewDidLoad (oder woanders) und Sie sehen dann die tintColor auf dem Bild.
Mark Moeykens
38

(@Zhaolong Zhong Post kann nicht bearbeitet werden)

In Swift 3.0 können Sie Folgendes tun:

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

yourImageView.image = image

yourImageView.tintColor = UIColor.blue
odemolliens
quelle
19

In Swift 2.0+ können Sie Folgendes tun:

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

yourImageView.image = image

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

Schnelle Version: 5.2

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

Ziel c

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

Oder

Sie können dies auch einfach für Ihr Asset festlegen.

Geben Sie hier die Bildbeschreibung ein

Nischal Hada
quelle
7

Einen Schritt weiter. Dies ist eine Drop-In-Unterklasse von UIImageView. (Keine genaue Lösung für die ursprüngliche Frage.) Verwenden Sie diese Option im Interface Builder, indem Sie den Klassennamen auf TintedImageView setzen. Aktualisierungen in Echtzeit innerhalb des Designers, wenn sich die Farbtonfarbe ändert.

(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
quelle
2
funktioniert nicht, aber es ändert func configure in: self.image = self.image? .withRenderingMode (UIImageRenderingMode.alwaysTemplate) let color = super.tintColor super.tintColor = UIColor.clear super.tintColor = color
lolo_house
5

Machen Sie die Bildansicht

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

Mach das Bild

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

Verdrahten Sie sie miteinander

    imageView?.image = image

Zeigen Sie es an

view.addSubview(imageView)
Gary Davies
quelle
1

alles gesagt ist richtig. Mein Beitrag Wenn Sie sich nicht auf jede UiImageView anwenden können / wollen ODER aus Effizienzgründen müssen Sie EINMAL rendern (oder ein Beispiel für Zellen mit Tabellenansichten).

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
    }

Und setzen Sie dieses UIImage auf alle UI-Elemente.

ingconti
quelle
1

@odemolliens Antwort sollte einfach funktionieren.

Wenn Sie jedoch weiterhin Probleme haben, stellen Sie sicher, dass sich die Farbtonfarbe, die Sie auf UIImageView anwenden, von der im Interface Builder definierten unterscheidet.

rockdaswift
quelle