Est-il possible de modifier UIImage
les a renderingMode
depuis un storyboard ou un éditeur xib?
Le but est de s'appliquer tintColor
à l' UIImageView
objet particulier .
Est-il possible de modifier UIImage
les a renderingMode
depuis un storyboard ou un éditeur xib?
Le but est de s'appliquer tintColor
à l' UIImageView
objet particulier .
Réponses:
Voici comment vous pouvez le faire dans des fichiers .xib ou storyboard:
(Obj-C) Créez une catégorie sur 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) Créez une extension pour 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)
}
}
Ensuite, dans l'inspecteur d'identité du fichier xib, ajoutez un attribut d'exécution:
Vous pouvez définir le mode de rendu de l'image non pas dans le .xib
fichier, mais dans une .xcassets
bibliothèque.
Après avoir ajouté une image à une bibliothèque de ressources, sélectionnez l'image et ouvrez l'inspecteur d'attributs sur le côté droit de Xcode. Recherchez l'attribut «Rendu en tant que» et définissez-le sur «modèle».
Après avoir défini le mode de rendu d'une image, vous pouvez ajouter une couleur de teinte UIImageView
dans un fichier .xib
ou .storyboard
pour ajuster la couleur de l'image.
Cela définit la propriété sur l'image partout où elle est utilisée plutôt que dans un seul fichier de générateur d'interface, mais dans presque tous les cas (que j'ai rencontrés), c'est le comportement que vous souhaitez.
Quelques points à noter:
UIImageView
. Je n'ai pas examiné cela en profondeur.UIKitComponents
images telles que les images dans UIButton
's et UIBarButtonItem
' s.UIImageView
, donc la couleur de teinte n'est pas toujours affichée lors de l'exécution de l'application.
L'utilisation du mode de rendu de modèle avec une UIImageView dans un storyboard ou xib est très boguée, à la fois sur iOS 7 et iOS 8.
UIImage n'est pas correctement décodée à partir du storyboard / xib. Si vous inspectez la imageView.image.renderingMode
propriété dans la viewDidLoad
méthode, vous remarquerez qu'elle l'est toujours UIImageRenderingModeAutomatic
, même si vous la définissez sur Render As Template Image dans votre fichier xcassets.
Pour contourner le problème, vous devez définir manuellement le mode de rendu:
self.imageView.image = [self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
L'interface utilisateur est correctement décodée et sa renderingMode
propriété reflète ce qui a été choisi dans le fichier xcassets mais l'image n'est pas teintée.
Pour contourner le problème, vous avez deux options:
tintColor
propriété dans le attributs d'exécution définis utilisateur au lieu du volet de l'inspecteur d'attributs.ou
UIColor *tintColor = self.imageView.tintColor;
self.imageView.tintColor = nil;
self.imageView.tintColor = tintColor;
Vous pouvez choisir votre option préférée, les deux teignant correctement l'image.
(Si vous compilez avec Xcode 6.2, faites simplement self.imageView.tintColor = self.imageView.tintColor;
mais cela ne fonctionne plus si vous compilez avec Xcode 6.3)
Si vous devez prendre en charge à la fois iOS 7 et iOS 8, vous aurez besoin des deux solutions de contournement. Si vous devez uniquement prendre en charge iOS 8, une seule solution de contournement est nécessaire.
La définition de imageView RenderingMode pour utiliser la couleur de teinte dans le storyboard peut être réduite à une seule ligne:
[self.imageView setImage:[self.imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
Ensuite, l'image et la couleur de teinte peuvent toutes être définies dans le Storyboard.
Vous pouvez résoudre les problèmes .xib avec une extension:
import UIKit
// fixing Bug in XCode
// http://openradar.appspot.com/18448072
extension UIImageView {
override open func awakeFromNib() {
super.awakeFromNib()
self.tintColorDidChange()
}
}
Source: https://gist.github.com/buechner/3b97000a6570a2bfbc99c005cb010bac
Incroyable, ce bug existe depuis 4 à 5 ans maintenant.
Vous ne pouvez pas définir renderingMode
à partir de storyboard
ou xib
. Il pourrait accéder par programme.
ex:
UIImage *unSeletedImage = [UIImage imageNamed:@"UnSelected.png"];
selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UIImage *selectedImage = [unSeletedImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Définissez tintColor & Class dans Storyboard.
//
// 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
}
}
C'est très facile à réparer
Créez simplement la classe UIImageViewPDF et utilisez-la dans votre 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
Une autre solution consiste à créer une UIImageView
sous - classe:
final class TemplateImageView: UIImageView {
override func awakeFromNib() {
super.awakeFromNib()
guard let oldImage = image else { return }
image = nil
image = oldImage.withRenderingMode(.alwaysTemplate)
}
}
Ensuite, définissez simplement la classe dans Interface Builder sur TemplateImageView
.
Un moyen simple d'être défini à partir de 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)
}
}
}
}
Fonctionne bien sur iOS 10 et Swift 3
Dans iOS 9, le paramètre tintColor
propriété dans Interface Builder est toujours boguée.
Notez qu'une solution de travail en plus d'écrire des lignes modifiant directement les ImageView
propriétés est de définir Render As: Template Image dans le catalogue d'actifs, et d'appeler par exemple:
[[UIImageView appearanceWhenContainedInInstancesOfClasses:@[[MyView class]]] setTintColor:[UIColor whiteColor]];
Si vous créez un IBOutlet, vous pouvez le modifier dans votre méthode awakeFromNib comme ceci ...
self.myImageView.image = [self.myImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
Bien que la réponse de @ Moby soit plus correcte, cela pourrait être plus succinct.
Fou ce bug est toujours dans iOS 12.1! Pour les storyboards / xibs: l'ajout d'une balise à UIImageView peut être une solution rapide.
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)
}
}
}
Dans le storyboard, sélectionnez UIImageView et sélectionnez l'inspecteur, définissez property renderModeTemplate
= On
In Storyboard
Comme Rudolf l'a également mentionné ci - dessus , je définirais une classe simple, comme ceci:
import UIKit
@IBDesignable class TintImage: UIImageView{
override func layoutSubviews() {
super.layoutSubviews()
image = image?.withRenderingMode(.alwaysTemplate)
}
}
Après cette définition, ajoutez simplement une vue d'image au storyboard et sélectionnez sa classe personnalisée en tant que TintImage
. Cela activera la sélection "Teinte" dans le storyboard.