web-dev-qa-db-fra.com

UIImageView ne teinte pas toujours l'image du modèle

Dans le cas ci-dessous, il y a deux UIImageViews avec les mêmes paramètres et le même modèle d'image ... Mais on teinte l'image, et l'autre pas

J'ai dupliqué le travail UIImageView et l'ai placé à la place de l'autre et cela a fonctionné. Cela m'est arrivé plusieurs fois et cette solution a toujours fonctionné, mais je me demande encore qu'est-ce que j'ai pu faire de mal? Peut-il s'agir d'un bogue Xcode? Est-ce que quelque chose de similaire vous est arrivé? J'ai Xcode 8.1.

Xcode screenshot

Xcode screenshot

46
Zuzana Paulis

Solution facile:

enter image description here

Ajoutez simplement un nouvel attribut d'exécution qui définira la teinteCouleur de UIImageView sur la couleur spécifiée et garantira que l'image est teintée.

Vous devrez toujours définir le rendu de votre image en tant qu’image modèle dans votre fichier Images.xcassets.

De cette façon, vous n’avez pas besoin de points de vente, d’extensions ou de lignes de code supplémentaires.

Notez également que: La teinteCouleur n'apparaît pas dans l'attribut défini par l'utilisateur si la teinteCouleur de la vue est de la même couleur, elles doivent être différentes.

112
David Rees

La meilleure solution que j'ai trouvée ne nécessite pas de sous-classe ou un autre attribut IBInspectable:

import UIKit

extension UIImageView {
    override open func awakeFromNib() {
        super.awakeFromNib()
        tintColorDidChange()
    }
}
48
allaire

Le problème provient de la valeur de teinte n'ayant pas d'état nul (dans l'interface utilisateur de Storyboard/Interface Builder). Pour que Xcode puisse décider si une teinte doit être appliquée à un UIImageView, il semble y avoir un test supplémentaire. Dans Xcode, ceci se fait apparemment en évaluant les contraintes appliquées à UIImageView. Pour autant que je sache, ce test est non documenté.

Si vous avez uniquement une contrainte "Espacement au plus proche voisin" sur deux (ou un) côtés de votre UIImageView, la teinte n'est pas appliquée quelle que soit la valeur définie pour UIImage.renderingMode.

Si vous avez une contrainte "Espacement au plus proche voisin" sur trois côtés (ou tous) de votre UIImageView, la teinte est appliquée si le UIImage.renderingMode est réglé sur .alwaysTemplate.

Dans une approche uniquement Storyboard/Interface Builder, vous définissez le UIImage.renderingMode d'une image en l'ajoutant à un catalogue d'actifs, puis en modifiant la propriété "Rendre en tant que" de l'ensemble d'images en "Modèle d'image".

24
richardjsimkins

Essayez de définir tintColor par programme; cela a résolu le problème pour moi.

16

Je pense qu'il y a un bug dans UIImageView. Si vous définissez une couleur de teinte dans le story-board, cette teinte ne sera pas appliquée, même lorsque l'actif est configuré pour un rendu en tant que modèle.

La solution de contournement consiste à appliquer la couleur de teinte à la vue parent de UIImageView dans le storyboard.

Vous pouvez également définir la teinte sur nil, puis à nouveau dans le code en liant UIImageView à une prise.

14
paddlefish

utilisez cette extension pour définir UIImageView tintColor à partir du générateur d'interface.

extension UIImageView {
    @IBInspectable var imageColor: UIColor! {
        set {
            super.tintColor = newValue
        }
        get {
            return super.tintColor
        }
    }
} 
6
Mina

En supprimant mon UIImageView existant et en ajoutant un nouveau, mon problème avait disparu. Apparemment, vous devez ajouter UIImageView APRES avoir ajouté les images dans le dossier Assets.

3
rudymatos

Peut-être que cela m'aidera à me taper la tête pendant une heure, jusqu'à ce que je réalise quelque chose que je ne comprends toujours pas.

J'avais ma vue dans mon fichier .nib et toutes les prises sauf une (le UIImageView) avaient une couleur non teintée par défaut. J'ai essayé toutes les réponses suggérées mais le problème a été résolu en sélectionnant une couleur de teinte par défaut pour la changer par programme.

enter image description here

enter image description here

Est-ce que c'est un bug?

3
Reimond Hill

L'astuce d'attribut d'exécution n'a pas fonctionné pour moi. J'ai fait cette classe juste pour réparer ce genre de choses. Vous allez simplement définir dans cette classe toutes les vues problématiques.

final class TintedImageView: UIImageView {

    // WORKAROUND: Template images are not tinted when set using the Interface Builder.
    override func layoutSubviews() {
        super.layoutSubviews()
        let preferredTintColor = tintColor
        tintColor = nil
        tintColor = preferredTintColor
    }

}
2
Marlo Quidato

Comme @richardjsimkins l'a mentionné, cela semble au moins dans certains cas être lié à des contraintes. Dans mon cas, je voulais ajouter une image au centre de l'écran de lancement, car dans ce cas, je ne suis pas en mesure de définir la teinte par couleur par programmation. Je devais trouver une solution de Storyboard pure.

J'ai trouvé que la teinte n'était pas définie lors du centrage de la vue avec des contraintes, c'est-à-dire centrer horizontalement/verticalement dans une zone sécurisée, ce qui correspond au fait qu'elle ne comporte aucune contrainte "Espacement au plus proche voisin".

Au lieu de cela, j'ai ajouté une vue de pile avec des contraintes relatives aux zones sécurisées précédant/suivant/haut/bas, puis incorporant la vue d'image dans la zone sécurisée avec le centre d'alignement, le remplissage de distribution. Cela a pour conséquence le même positionnement que le centrage direct de l'imageView dans la zone de sécurité, ce qui a permis à la teinteColor de prendre effet.

Je n'aime pas avoir à résoudre l'utilisation d'une vue de pile pour forcer le fonctionnement de tintColor, mais je pense que c'est une solution de contournement petite et relativement propre au bogue.

1
Darumar

Conserver la couleur de teinte par défaut dans le storyboard enter image description here

et ajoutez un attribut d’exécution défini par l’utilisateur avec la couleur choisie enter image description here

Le storyboard montrera l'image avec la teinte par défaut, mais lorsque vous courrez, il montrera la couleur sélectionnée.

0
Krutika Sonawala

J'ai eu ce problème avec XCode 10.3. C'est un bogue XCode qui semble être lié à l'ajout d'une image au storyboard avant de l'ajouter aux ressources.

Ce qui m’a aidé, c’est de changer la couleur de teinte en une couleur aléatoire, puis de la rétablir par défaut.

En conséquence, XCode a ajouté <color key="tintColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> au storyboard XML qui manquait auparavant. Bien qu'il soit ajouté en tant que colorSpace="custom" le générateur XCode l'affiche sous la forme default.

0
Gene S