Od bieli iOS do przezroczystej warstwy gradientu jest szary

87

Mam CAGradientLayer wstawioną na dole tego małego widoku szczegółowego, który pojawia się u dołu aplikacji. Jak widać, ustawiłem kolory z białego na wyraźne, ale pojawia się ten dziwny szary odcień. Jakieś pomysły?

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

Oto problematyczny widok:

Oto problematyczny widok

Eric Gao
źródło
Co jest pod warstwą?
trojanfoe
MapView. Mogę ustawić warstwę na clearColor i clearColor i będzie ona w pełni przezroczysta.
Eric Gao
Co próbuję uzyskać: czy warstwa pod tą warstwą jest szara?
trojanfoe
Nie ... nie należy wstawiać podwarstwy o indeksie 0 umieszczać tej warstwy na najgłębszej warstwie? A jeśli nie wstawię podwarstwy, tło widoku jest jasne, jak powinno. Dopiero gdy ustawię gradient, pojawia się ten szary kolor.
Eric Gao
Czy próbowałeś zamiast tego ustawić go na self.detailView.layer.mask? (self.detailView.layer.mask = layer;)
Akaino

Odpowiedzi:

185

clearColor ma czarny kanał koloru z alfa 0, więc musiałem użyć

[UIColor colorWithWhite:1 alpha:0]

i działa dobrze.

Eric Gao
źródło
16
Zastępuje czarny cień białym cieniem. Wciąż nieprzejrzysty
RealNmae
2
Ważne - w 2018 r. Rozważ to podejście: stackoverflow.com/a/25408833/294884
Fattie
7
@RealNmae Jeśli chcesz przejść od koloru do przezroczystego, użyj UIColor.startColor i UIColor.startColor.withAlphaComponent (0.0) jako dwóch kolorów.
Conor
@Conor To właściwie poprawna odpowiedź - dzięki, działa idealnie niezależnie od koloru
SomaMan
60

W Swift To zadziałało dla mnie,

UIColor.white.withAlphaComponent(0).cgColor
Mohammad Zaid Pathan
źródło
3
Nie zapomnij dodać .cgColor, jak pokazano w odpowiedzi !!! Przypadkowo użyłem UIColor.white.withAlphaComponent (0) i drapałem się po głowie przez godzinę, zastanawiając się, dlaczego wciąż jest szara.
SnoopyProtocol
21

Warto zauważyć, że każdy inny kolor będzie działał w ten sposób ... używając kombinacji dwóch powyższych odpowiedzi ....

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

Szybki 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
źródło
12

Składnia Swift 3,

UIColor(white: 1, alpha: 0).cgColor
Stuart Casarotto
źródło
1

Powyższe odpowiedzi, takie jak:

UIColor.white.withAlphaComponent(0).cgColor

i

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

powinien działać w kategoriach uzyskania wyraźnego fragmentu gradientu (zamiast szarego, do którego odnosi się OP). Jeśli jednak nadal widzisz przezroczystą biel, podczas gdy powinieneś widzieć wyraźny kolor, upewnij się, backgroundColorże widok, do którego stosujesz gradient, również jest wyraźny.

Domyślnie kolor tła tego widoku będzie prawdopodobnie biały (lub ciemny kolor, jeśli urządzenie jest w trybie ciemnym), więc po zastosowaniu gradientu jego wyraźna część zostanie „zablokowana” przez sam widok backgroundColor. Ustaw to, aby było jasne i powinieneś być gotowy.

Brian Sachetta
źródło
0

Tyle samo, mimo zastosowania czystej bieli nadal mam szary kolor.

Więc zmieniłem podejście i wybrałem maskę zamiast gradientu. Efekt końcowy jest taki sam, no cóż, lepszy, ponieważ ten działa w każdej sytuacji, nie tylko wtedy, gdy masz odpowiednie tło.

Nie próbowałem tego kodu z IB, ale mam nadzieję, że to też działa. Po prostu ustaw backgroundColori gotowe.

@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
źródło
0

Warto zauważyć, że aby obsługiwać gradienty biały / czarny (lub naprawdę dowolny kolor z jasnymi / ciemnymi efektami) w oparciu o tryb jasny / ciemny w iOS 13, podejście to działa również z nowymi kolorami systemowymi:

gradientLayer.colors = [
    UIColor.systemBackground.cgColor,
    UIColor.systemBackground.withAlphaComponent(0).cgColor] 
Jake
źródło