it-swarm.com.de

Ändern Sie den UIImage-RenderingMode aus einer Storyboard-/Xib-Datei

Ist es möglich, eine UIImagerenderingMode von einem Storyboard- oder Xib-Editor aus zu ändern?

Das Ziel ist, tintColor auf das jeweilige UIImageView-Objekt anzuwenden.

82

So können Sie dies in .xib- oder Storyboard-Dateien tun:

(Obj-C) Erstellen Sie eine Kategorie für UIImageView:

@interface UIImageView (Utils)

- (void)setImageRenderingMode:(UIImageRenderingMode)renderMode;

@end

@implementation UIImageView (Utils)

- (void)setImageRenderingMode:(UIImageRenderingMode)renderMode
{
    NSAssert(self.image, @"Image must be set before setting rendering mode");
    self.image = [self.image imageWithRenderingMode:renderMode];
}

@end

(Swift 4) Erstellen Sie eine Erweiterung für UIImageView:

extension UIImageView {
    func setImageRenderingMode(_ renderMode: UIImage.RenderingMode) {
        assert(image != nil, "Image must be set before setting rendering mode")
        // AlwaysOriginal as an example
        image = image?.withRenderingMode(.alwaysOriginal)
    }
}

Fügen Sie dann im Identity Inspector in der Xib-Datei ein Laufzeitattribut hinzu:

enter image description here

93
Snowman

Sie können den Bildwiedergabemodus nicht in der .xib-Datei festlegen, sondern in einer .xcassets-Bibliothek.

Nachdem Sie ein Bild zu einer Objektbibliothek hinzugefügt haben, wählen Sie das Bild aus und öffnen Sie den Attribut-Inspector auf der rechten Seite von Xcode. Suchen Sie das Attribut 'Render As' und setzen Sie es auf 'template'.

Nachdem Sie den Wiedergabemodus für ein Bild festgelegt haben, können Sie der UIImageView in einer .xib- oder .storyboard-Datei eine Farbtonfarbe hinzufügen, um die Bildfarbe anzupassen.

Dadurch wird die Eigenschaft für das Image festgelegt, wo immer sie verwendet wird, und nicht nur in einer Interface-Builder-Datei. In fast allen Fällen (die ich je gesehen habe) ist dies das gewünschte Verhalten.

Screenshot of Xcode showing attributes inspector for an image

Ein paar Dinge zu beachten:

  • Die Bildfarbe scheint sich im Interface Builder (ab Xcode 6.1.1) nicht geändert zu haben, funktioniert jedoch, wenn die Anwendung ausgeführt wird.
  • Ich habe einige Probleme mit dieser Funktion erlebt und in einigen Situationen musste ich die Variable UIImageView entfernen und erneut hinzufügen. Ich habe das nicht tief untersucht.
  • Dies funktioniert auch gut für andere UIKitComponents-Objekte, z. B. für Bilder in UIButton_s und UIBarButtonItem_s.
  • Wenn Sie eine Reihe von weißen Bildern haben, die in Ihrer Objektbibliothek unsichtbar sind, wird das Leben um bis zu 10-fach verbessert, wenn Sie sie in schwarze/transparente Bilder umwandeln und den Rendermodus ändern.
174
Anthony Mattox

Die Verwendung des Vorlagenrendermodus mit einer UIImageView in einem Storyboard oder Xib ist sowohl unter iOS 7 als auch unter iOS 8 sehr fehlerhaft.

Unter iOS 7

Der UIImage wird vom Storyboard/Xib nicht richtig dekodiert. Wenn Sie die imageView.image.renderingMode-Eigenschaft in der viewDidLoad-Methode untersuchen, werden Sie feststellen, dass es sich stets um UIImageRenderingModeAutomatic handelt, selbst wenn Sie in Ihrer Xcassets-Datei auf Als Vorlagenbild setzen.

Um dieses Problem zu umgehen, müssen Sie den Rendermodus manuell einstellen:

self.imageView.image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

Auf iOS 8

Der UIImage ist ordnungsgemäß dekodiert und seine renderingMode -Eigenschaft spiegelt wider, was in der xcassets-Datei ausgewählt wurde, das Bild ist jedoch nicht getönt.

Um dieses Problem zu umgehen, haben Sie zwei Möglichkeiten:

  1. Legen Sie die tintColor -Eigenschaft im Benutzerdefinierte Laufzeitattribute statt im Informationsfenster "Attribute" fest.

oder

  1. Setzen Sie tintColor manuell zurück:
UIColor *tintColor = self.imageView.tintColor;
self.imageView.tintColor = nil;
self.imageView.tintColor = tintColor;

Sie können Ihre bevorzugte Option auswählen und das Bild richtig färben.

(Wenn Sie mit Xcode 6.2 kompilieren, reicht es aus, self.imageView.tintColor = self.imageView.tintColor; zu tun. Dies funktioniert jedoch nicht mehr, wenn Sie mit Xcode 6.3 kompilieren.)

Fazit

Wenn Sie sowohl iOS 7 als auch iOS 8 unterstützen müssen, benötigen Sie beide Problemumgehungen. Wenn Sie nur iOS 8 unterstützen müssen, ist nur eine Problemumgehung erforderlich.

42
0xced

Wenn Sie imageView RenderingMode so einstellen, dass die Farbtonfarbe im Storyboard verwendet wird, kann dies auf einen Einzeiler reduziert werden:

[self.imageView setImage:[self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];

Anschließend können Bild und Farbton im Storyboard eingestellt werden.

15
middleseatman

Sie können .xib-Probleme mit einer Erweiterung beheben:

import UIKit

// fixing Bug in XCode
// http://openradar.appspot.com/18448072
extension UIImageView {
    override open func awakeFromNib() {
        super.awakeFromNib()
        self.tintColorDidChange()
    }
}

Quelle: https://Gist.github.com/buechner/3b97000a6570a2bfbc99c005cb010bac

Erstaunlich, dieser Fehler gibt es jetzt schon seit 4-5 Jahren.

10
nikans

Sie können renderingMode nicht auf storyboard oder xib einstellen. Es könnte programmgesteuert darauf zugegriffen werden.

ex: 

UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
8
Mani

Legen Sie im Storyboard tintColor & Class fest.

//
//  TintColoredImageView.Swift
//  TintColoredImageView
//
//  Created by Dmitry Utmanov on 14/07/16.
//  Copyright © 2016 Dmitry Utmanov. All rights reserved.
//

import UIKit

@IBDesignable class TintColoredImageView: UIImageView {

    override var image: UIImage? {
        didSet {
            let _tintColor = self.tintColor
            self.tintColor = nil
            self.tintColor = _tintColor
        }
    }


    override init(frame: CGRect) {
        super.init(frame: frame)
        initialize()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        initialize()
    }

    override init(image: UIImage?) {
        super.init(image: image)
        initialize()
    }

    override init(image: UIImage?, highlightedImage: UIImage?) {
        super.init(image: image, highlightedImage: highlightedImage)
        initialize()
    }

    func initialize() {
        let _tintColor = self.tintColor
        self.tintColor = nil
        self.tintColor = _tintColor
    }

}
8
Dmitry Coolerov

Es ist sehr leicht zu beheben

Erstellen Sie einfach die Klasse UIImageViewPDF und verwenden Sie sie in Ihrem Storyboard

IB_DESIGNABLE
@interface UIImageViewPDF : UIImageView

@end

@implementation UIImageViewPDF

- (void) didMoveToSuperview
{
    [super didMoveToSuperview];
    self.image = [self.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    id color = self.tintColor;
    self.tintColor = color;
}

@end
4
Igor Popov

Eine andere Lösung ist das Erstellen einer UIImageView-Unterklasse:

final class TemplateImageView: UIImageView {
    override func awakeFromNib() {
        super.awakeFromNib()
        guard let oldImage = image else { return }
        image = nil
        image = oldImage.withRenderingMode(.alwaysTemplate)
    }
}

Dann setzen Sie einfach die Klasse im Interface Builder auf TemplateImageView.

3

Einfache Möglichkeit, vom Storyboard aus eingestellt zu werden:

@IBDesignable
public class CustomImageView: UIImageView {
    @IBInspectable var alwaysTemplate: Bool = false {
        didSet {
            if alwaysTemplate {
                self.image = self.image?.withRenderingMode(.alwaysTemplate)
            } else {
                self.image = self.image?.withRenderingMode(.alwaysOriginal)
            }

        }
    }
}

Funktioniert gut auf iOS 10 und Swift 3

2
Rodrigo

In iOS 9 ist die Einstellung tintColor im Interface Builder noch fehlerhaft.

Beachten Sie, dass eine funktionierende Lösung neben dem Schreiben von Zeilen, die direkt ImageView -Eigenschaften ändern, darin besteht, Render As: Template Image im Asset-Katalog festzulegen und z. B. aufzurufen:

[[UIImageView appearanceWhenContainedInInstancesOfClasses:@[[MyView class]]] setTintColor:[UIColor whiteColor]];
1
yarp

Verrückt ist dieser Bug noch in iOS 12.1! Für Storyboards/Xibs: Das Hinzufügen eines Tags zu UIImageView kann eine schnelle Lösung sein.

Swift 4.2

view.viewWithTag(1)?.tintColorDidChange()
0
Jayden Irwin

Wenn Sie ein IBOutlet erstellen, können Sie es wie folgt in Ihrer awakeFromNib-Methode ändern.

self.myImageView.image = [self.myImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];

@ Mobys Antwort ist zwar korrekter - dies könnte prägnanter sein.

0
amergin

Dieses Problem wurde durch das Hinzufügen des Laufzeitattributs tintColor im Interface Builder behoben.

HINWEIS: Sie müssen weiterhin festlegen, dass Ihr Bild in Ihrer Images.xcassets-Datei als Vorlagenbild dargestellt wird.

 enter image description here

0
Sunil Targe