105 votes

Modifier le mode de rendu UIImage à partir d'un fichier storyboard/xib

Est-il possible de modifier le renderingMode d'une UIImage à partir d'un storyboard ou d'un éditeur xib?

Le but est d'appliquer tintColor à l'objet UIImageView particulier.

212voto

Anthony Mattox Points 895

Vous pouvez définir le mode de rendu de l'image non pas dans le fichier .xib, mais dans une bibliothèque .xcassets.

Après avoir ajouté une image à une bibliothèque d'images, sélectionnez l'image et ouvrez l'inspecteur d'attributs situé sur le côté droit de Xcode. Recherchez l'attribut 'Rendu comme' 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 à l'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 interface builder, mais dans presque tous les cas (que j'ai rencontrés), c'est le comportement souhaité.

Capture d'écran de Xcode montrant l'inspecteur d'attributs pour une image

Quelques points à noter:

  • La couleur de l'image ne semblera pas avoir changé dans l'interface builder (à partir de Xcode 6.1.1), mais fonctionnera lorsque l'application sera exécutée.
  • J'ai rencontré quelques problèmes avec cette fonctionnalité et dans certaines situations, j'ai dû supprimer et réajouter l'UIImageView. Je n'ai pas creusé plus profondément.
  • Cela fonctionne également très bien sur d'autres UIKitComponents comme les images dans les UIButton et les UIBarButtonItem.
  • Si vous avez une série d'images blanches qui sont invisibles dans votre bibliothèque d'images, les rendre noires/transparents et changer le mode de rendu rendra votre vie jusqu'à 10 fois meilleure.

103voto

moby Points 6711

Voici comment vous pouvez le faire dans les 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é dans le fichier xib, ajoutez un attribut d'exécution :

enter image description here

43voto

0xced Points 10972

En utilisant le mode de rendu de modèle avec un UIImageView dans un storyboard ou xib, c'est très buggy, à la fois sur iOS 7 et iOS 8.

Sur iOS 7

L'UIImage n'est pas correctement décodée du storyboard/xib. Si vous inspectez la propriété imageView.image.renderingMode dans la méthode viewDidLoad, vous remarquerez que c'est toujours UIImageRenderingModeAutomatic, même si vous le définissez comme Rendu En tant qu'image du modèle dans votre fichier xcassets.

Pour contourner cela, vous devez définir manuellement le mode de rendu:

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

Sur iOS 8

L'UIImage est correctement décodée et sa propriété renderingMode reflète ce qui a été choisi dans le fichier xcassets mais l'image n'est pas teintée.

Pour contourner cela, vous avez deux options:

  1. Définir la propriété tintColor dans les Attributs d'exécution utilisateur définis au lieu du volet Inspecteur des attributs.

ou

  1. Redéfinir manuellement la teinte:

    UIColor *tintColor = self.imageView.tintColor; self.imageView.tintColor = nil; self.imageView.tintColor = tintColor;

Vous pouvez choisir votre option préférée, les deux teintent correctement l'image.

(Si vous compilez avec Xcode 6.2, il suffit de faire self.imageView.tintColor = self.imageView.tintColor; mais cela ne fonctionne plus si vous compilez avec Xcode 6.3)

Conclusion

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.

17voto

middleseatman Points 98

Le réglage du mode de rendu de l'imageView pour utiliser la couleur de teinte dans le storyboard peut être réduit à une seule ligne :

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

Ensuite, l'image et la couleur de teinte peuvent toutes deux être définies dans le Storyboard.

13voto

nikans Points 519

Vous pouvez résoudre les problèmes .xib avec une extension:

import UIKit

// Réparer Bug dans 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 environ 4-5 ans maintenant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X