Ist es möglich, a UIImage
's renderingMode
über ein Storyboard oder einen xib-Editor zu ändern ?
Ziel ist es, tintColor
auf das jeweilige UIImageView
Objekt anzuwenden .
Ist es möglich, a UIImage
's renderingMode
über ein Storyboard oder einen xib-Editor zu ändern ?
Ziel ist es, tintColor
auf das jeweilige UIImageView
Objekt anzuwenden .
Antworten:
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 Identitätsinspektor in der xib-Datei ein Laufzeitattribut hinzu:
Sie können den Bildwiedergabemodus nicht in der .xib
Datei, sondern in einer .xcassets
Bibliothek einstellen .
Wählen Sie nach dem Hinzufügen eines Bildes zu einer Asset-Bibliothek das Bild aus und öffnen Sie den Attributinspektor auf der rechten Seite von Xcode. Suchen Sie das Attribut 'Rendern als' und setzen Sie es auf 'Vorlage'.
Nachdem Sie den Rendering-Modus eines Bildes festgelegt haben, können Sie der Datei UIImageView
in a .xib
oder eine Farbtonfarbe hinzufügen .storyboard
, um die Bildfarbe anzupassen.
Dadurch wird die Eigenschaft für das Image überall dort festgelegt, wo sie verwendet wird, und nicht nur in einer Interface Builder-Datei. In fast allen Fällen (auf die ich gestoßen bin) ist dies jedoch das gewünschte Verhalten.
Ein paar Dinge zu beachten:
UIImageView
. Ich habe das nicht tief untersucht.UIKitComponents
wie Bildern in UIButton
's und UIBarButtonItem
' s.UIImageView
, sodass die Farbtonfarbe beim Ausführen der App nicht immer angezeigt wird.
Die Verwendung des Vorlagen-Rendering-Modus mit einem UIImageView in einem Storyboard oder xib ist sowohl unter iOS 7 als auch unter iOS 8 sehr fehlerhaft.
Das UIImage wird vom Storyboard / xib nicht richtig dekodiert. Wenn Sie die imageView.image.renderingMode
Eigenschaft in der viewDidLoad
Methode überprüfen , werden Sie feststellen, dass dies immer der Fall ist UIImageRenderingModeAutomatic
, auch wenn Sie sie in Ihrer xcassets-Datei auf Als Vorlagenbild rendern festlegen.
Um dies zu umgehen, müssen Sie den Rendering-Modus manuell einstellen:
self.imageView.image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Das UIImage wird ordnungsgemäß dekodiert und seine renderingMode
Eigenschaft spiegelt wider, was in der xcassets-Datei ausgewählt wurde, aber das Bild ist nicht getönt.
Um dies zu umgehen, haben Sie zwei Möglichkeiten:
tintColor
Eigenschaft im benutzerdefinierten Laufzeitattribut anstelle des Inspektorbereichs "Attribute" fest.oder
UIColor *tintColor = self.imageView.tintColor;
self.imageView.tintColor = nil;
self.imageView.tintColor = tintColor;
Sie können Ihre bevorzugte Option auswählen, wobei beide das Bild richtig tönen.
(Wenn Sie mit Xcode 6.2 kompilieren, self.imageView.tintColor = self.imageView.tintColor;
reicht es aus, dies nur zu tun , aber dies funktioniert nicht mehr, wenn Sie mit Xcode 6.3 kompilieren.)
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.
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]];
Dann können das Bild und die Farbtonfarbe im Storyboard festgelegt werden.
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 schon seit 4-5 Jahren.
Sie können renderingMode
weder von storyboard
noch einstellen xib
. Es könnte programmgesteuert darauf zugreifen.
Ex:
UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UIImage *selectedImage = [unSeletedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Stellen Sie tintColor & Class im Storyboard ein.
//
// 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
}
}
Es ist sehr einfach 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
Eine andere Lösung besteht darin, eine UIImageView
Unterklasse zu erstellen :
final class TemplateImageView: UIImageView {
override func awakeFromNib() {
super.awakeFromNib()
guard let oldImage = image else { return }
image = nil
image = oldImage.withRenderingMode(.alwaysTemplate)
}
}
Setzen Sie dann einfach die Klasse im Interface Builder auf TemplateImageView
.
Einfache Einstellung über Storyboard:
@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 unter iOS 10 und Swift 3
In iOS 9 ist das Festlegen der tintColor
Eigenschaft in Interface Builder immer noch fehlerhaft.
Beachten Sie, dass eine funktionierende Lösung neben dem Schreiben von Zeilen, die ImageView
Eigenschaften direkt ändern, darin besteht, Render As: Template Image im Asset-Katalog festzulegen und z.
[[UIImageView appearanceWhenContainedInInstancesOfClasses:@[[MyView class]]] setTintColor:[UIColor whiteColor]];
Ich habe dieses Problem durch Hinzufügen eines Laufzeitattributs tintColor
im Interface Builder behoben .
HINWEIS: Sie müssen Ihr Bild weiterhin so einstellen, dass es als Vorlagenbild in Ihrer Datei Images.xcassets gerendert wird.
Wenn Sie ein IBOutlet erstellen, können Sie es in Ihrer awakeFromNib-Methode wie folgt ändern ...
self.myImageView.image = [self.myImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Während @ Mobys Antwort korrekter ist, könnte dies prägnanter sein.
Verrückt, dieser Fehler ist immer noch in iOS 12.1! Für Storyboards / Xibs: Das Hinzufügen eines Tags zur UIImageView kann eine schnelle Lösung sein.
Swift 4.2
view.viewWithTag(1)?.tintColorDidChange()
extension UIImageView {
@IBInspectable var renderModeTemplate : Bool {
get{
return image?.renderingMode == .alwaysTemplate
}
set{
image = image?.withRenderingMode(newValue ? .alwaysTemplate:.alwaysOriginal)
}
}
}
Wählen Sie im Storyboard UIImageView und dann Inspector aus und setzen Sie property renderModeTemplate
= On
In Storyboard