iOS branco para camada de gradiente transparente é cinza

87

Eu tenho um CAGradientLayer inserido na parte inferior desta pequena exibição de detalhes que aparece na parte inferior do aplicativo. Como você pode ver, eu configurei as cores de branco para claro, mas há uma estranha tonalidade cinza que está aparecendo. Alguma ideia?

    // 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];

Aqui está a visão problemática:

Aqui está a visão problemática

Eric Gao
fonte
O que está sob a camada?
trojanfoe
O MapView. Posso definir a camada para usar clearColor e clearColor e será totalmente transparente.
Eric Gao
O que estou tentando descobrir: a camada sob esta camada é cinza?
trojanfoe
Não ... não deve insertSublayer no índice 0 colocar esta camada na camada mais profunda? E se eu não inserir a subcamada, o fundo da visualização é claro como deveria ser. É apenas quando eu defino o gradiente que a cor cinza aparece.
Eric Gao
Você já tentou defini-lo como self.detailView.layer.mask? (self.detailView.layer.mask = layer;)
Akaino

Respostas:

185

clearColor tem um canal de cor preta com alfa de 0, então tive que usar

[UIColor colorWithWhite:1 alpha:0]

e funciona bem.

Eric Gao
fonte
16
Ele substitui a sombra preta por sombra branca. Ainda não é transparente
RealNmae
2
Importante - para 2018, considere esta abordagem: stackoverflow.com/a/25408833/294884
Fattie
7
@RealNmae Se você quiser ir de uma cor para clara, use UIColor.startColor e UIColor.startColor.withAlphaComponent (0.0) como suas duas cores.
Conor
@Conor Esta é realmente a resposta correta - obrigado, funciona perfeitamente, independentemente da cor
SomaMan
60

Em Swift isso funcionou para mim,

UIColor.white.withAlphaComponent(0).cgColor
Mohammad Zaid Pathan
fonte
3
Não se esqueça de adicionar o .cgColor conforme mostrado na resposta !!! Eu acidentalmente usei UIColor.white.withAlphaComponent (0) e fiquei coçando minha cabeça por uma hora me perguntando por que ainda estava cinza.
SnoopyProtocol
21

Vale ressaltar que qualquer outra cor funcionará assim ... usando uma combinação das duas respostas acima ....

Objetivo 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
fonte
12

Sintaxe do Swift 3,

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

As respostas acima, como:

UIColor.white.withAlphaComponent(0).cgColor

e

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

deve funcionar em termos de obter uma parte de seu gradiente para ser clara (em vez do cinza a que o OP se refere). No entanto, se você ainda estiver vendo um branco transparente quando deveria estar vendo uma cor clara, certifique-se backgroundColorde que a visão à qual está aplicando o gradiente também esteja clara.

Por padrão, a cor de fundo dessa visualização provavelmente será branca (ou uma cor escura se o dispositivo estiver no modo escuro), portanto, quando você aplica o gradiente, a parte transparente dele será "bloqueada" pela própria visualização backgroundColor. Defina como claro e você estará pronto para ir.

Brian Sachetta
fonte
0

Como muitos, ainda tenho uma cor cinza, apesar de usar um branco claro.

Então mudei minha abordagem e optei por uma máscara em vez de um gradiente. O resultado final é o mesmo, bem, melhor, já que funciona em todas as situações, não apenas se você tiver um histórico adequado.

Não tentei este código com IB, mas espero que funcione bem. Basta configurar backgroundColore você está pronto para ir.

@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()
    }
}
Tancrede Chazallet
fonte
0

É importante notar que para lidar com gradientes de branco / preto (ou realmente qualquer cor com aparências claro / escuro) com base no modo claro / escuro no iOS 13, essa abordagem também funciona com as novas cores do sistema:

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