Le calque de dégradé blanc à transparent iOS est gris

87

J'ai un CAGradientLayer inséré au bas de cette petite vue détaillée qui apparaît au bas de l'application. Comme vous pouvez le voir, j'ai défini les couleurs du blanc à clair, mais il y a cette étrange teinte grise qui apparaît. Des idées?

    // Set up detail view frame and gradient
    [self.detailView setFrame:CGRectMake(0, 568, 320, 55)];

    CAGradientLayer *layer = [CAGradientLayer layer];
    layer.frame = self.detailView.bounds;
    layer.colors = [NSArray arrayWithObjects:(id)[UIColor whiteColor].CGColor, (id)[UIColor clearColor].CGColor, nil];
    layer.startPoint = CGPointMake(1.0f, 0.7f);
    layer.endPoint = CGPointMake(1.0f, 0.0f);
    [self.detailView.layer insertSublayer:layer atIndex:0];

Voici la vue problématique:

Voici la vue problématique

Eric Gao
la source
Qu'y a-t-il sous la couche?
trojanfoe
Le MapView. Je peux définir le calque pour utiliser clearColor et clearColor et il sera entièrement transparent.
Eric Gao
Ce à quoi j'essaie d'arriver: la couche sous cette couche est-elle grise?
trojanfoe
Non ... ne devrait-il pas insérerSublayer à l'index 0 mettre cette couche sur la couche la plus profonde? Et si je n'insère pas la sous-couche, l'arrière-plan de la vue est clair comme il se doit. Ce n'est que lorsque j'ai défini le dégradé que cette couleur grise apparaît.
Eric Gao
Avez-vous essayé de le définir sur self.detailView.layer.mask à la place? (self.detailView.layer.mask = layer;)
Akaino

Réponses:

185

clearColor a un canal de couleur noire avec un alpha de 0, j'ai donc dû utiliser

[UIColor colorWithWhite:1 alpha:0]

et cela fonctionne très bien.

Eric Gao
la source
16
Il remplace l'ombre noire par une ombre blanche. Toujours pas transparent
RealNmae
2
Important - pour 2018, considérez cette approche: stackoverflow.com/a/25408833/294884
Fattie
7
@RealNmae Si vous voulez passer d'une couleur à une couleur claire, utilisez UIColor.startColor et UIColor.startColor.withAlphaComponent (0.0) comme deux couleurs.
Conor
@Conor C'est en fait la bonne réponse - merci, fonctionne parfaitement quelle que soit la couleur
SomaMan
60

Dans Swift, cela a fonctionné pour moi,

UIColor.white.withAlphaComponent(0).cgColor
Mohammad Zaid Pathan
la source
3
N'oubliez pas d'ajouter le .cgColor comme indiqué dans la réponse !!! J'ai accidentellement utilisé UIColor.white.withAlphaComponent (0) et je me suis gratté la tête pendant une heure en me demandant pourquoi elle était encore grise.
SnoopyProtocol
21

Il convient de souligner que toute autre couleur fonctionnera comme ça ... en utilisant une combinaison des deux réponses ci-dessus ....

Objectif c

UIColor *colour = [UIColor redColor];
NSArray *colourArray = @[(id)[colour colorWithAlphaComponent:0.0f].CGColor,(id)colour.CGColor]
NSArray *locations = @[@0.2,@0.8];

CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.colors = colourArray;
gradientLayer.locations = locations;
gradientLayer.frame = self.frame;

[self.layer addSublayer:gradientLayer];

Swift 3

let colour:UIColor = .red
let colours:[CGColor] = [colour.withAlphaComponent(0.0).cgColor,colour.cgColor]
let locations:[NSNumber] = [0.2,0.8]

let gradientLayer = CAGradientLayer()
gradientLayer.colors = colours
gradientLayer.locations = locations
gradientLayer.frame = frame

layer.addSublayer(gradientLayer)
Magoo
la source
12

Syntaxe Swift 3,

UIColor(white: 1, alpha: 0).cgColor
Stuart Casarotto
la source
1

Les réponses ci-dessus telles que:

UIColor.white.withAlphaComponent(0).cgColor

et

UIColor(white: 1.0, alpha: 0.0).cgColor

devrait fonctionner en termes d'obtenir une partie de votre dégradé pour être claire (plutôt que le gris auquel OP fait référence). Cependant, si vous voyez toujours un blanc transparent alors que vous devriez voir une couleur claire, assurez-vous que backgroundColorla vue à laquelle vous appliquez le dégradé est également claire.

Par défaut, la couleur d'arrière-plan de cette vue sera probablement le blanc (ou une couleur sombre si l'appareil est en mode sombre), donc lorsque vous appliquez le dégradé, la partie claire de celui-ci sera "bloquée" par la vue backgroundColorelle - même. Réglez cela sur clair et vous devriez être prêt à partir.

Brian Sachetta
la source
0

Comme beaucoup, j'ai toujours une couleur grise malgré l'utilisation d'un blanc clair.

J'ai donc changé d'approche et opté pour un masque plutôt qu'un dégradé. Le résultat final est le même, enfin, mieux, car celui-ci fonctionne dans toutes les situations, pas seulement si vous avez un arrière-plan approprié.

Je n'ai pas essayé ce code avec IB, mais j'espère que cela fonctionne aussi. Préparez backgroundColor-vous et vous êtes prêt à partir.

@IBDesignable
class FadingView: UIView {

    @IBInspectable var startLocation: Double =   0.05 { didSet { updateLocations() }}
    @IBInspectable var endLocation:   Double =   0.95 { didSet { updateLocations() }}
    @IBInspectable var horizontalMode:  Bool =  false { didSet { updatePoints() }}
    @IBInspectable var diagonalMode:    Bool =  false { didSet { updatePoints() }}
    @IBInspectable var invertMode:      Bool =  false { didSet { updateColors() }}

    private let gradientLayerMask = CAGradientLayer()

    private func updatePoints() {
        if horizontalMode {
            gradientLayerMask.startPoint = diagonalMode ? CGPoint(x: 1, y: 0) : CGPoint(x: 0, y: 0.5)
            gradientLayerMask.endPoint   = diagonalMode ? CGPoint(x: 0, y: 1) : CGPoint(x: 1, y: 0.5)
        } else {
            gradientLayerMask.startPoint = diagonalMode ? CGPoint(x: 0, y: 0) : CGPoint(x: 0.5, y: 0)
            gradientLayerMask.endPoint   = diagonalMode ? CGPoint(x: 1, y: 1) : CGPoint(x: 0.5, y: 1)
        }
    }

    private func updateLocations() {
        gradientLayerMask.locations = [startLocation as NSNumber, endLocation as NSNumber]
    }

    private func updateSize() {
        gradientLayerMask.frame = bounds
    }

    private func updateColors() {
        gradientLayerMask.colors = invertMode ? [UIColor.white.cgColor, UIColor.clear.cgColor] : [UIColor.clear.cgColor, UIColor.white.cgColor]
    }

    private func commonInit() {
        layer.mask = gradientLayerMask
    }

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

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

    override func layoutSubviews() {
        super.layoutSubviews()
        updatePoints()
        updateLocations()
        updateSize()
        updateColors()
    }
}
Tancrède Chazallet
la source
0

Il convient de noter que pour gérer les dégradés blanc / noir (ou vraiment n'importe quelle couleur avec des apparences claires / foncées) basés sur le mode clair / sombre dans iOS 13, cette approche fonctionne également avec les nouvelles couleurs système:

gradientLayer.colors = [
    UIColor.systemBackground.cgColor,
    UIColor.systemBackground.withAlphaComponent(0).cgColor] 
Jake
la source