iOS от белого к прозрачному градиентному слою - серый

87

У меня есть CAGradientLayer, вставленный в нижнюю часть этого небольшого подробного представления, которое появляется в нижней части приложения. Как видите, я установил цвета с белого на прозрачный, но появляется странный серый оттенок. Любые идеи?

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

Вот проблемный взгляд:

Вот проблемный взгляд

Эрик Гао
источник
Что под слоем?
trojanfoe
MapView. Я могу настроить слой на использование clearColor и clearColor, и он будет полностью прозрачным.
Эрик Гао
Я пытаюсь понять: слой под этим слоем серый?
trojanfoe
Нет ... не следует ли insertSublayer с индексом 0 помещать этот слой в самый глубокий слой? И если я не вставлю подслой, фон представления будет четким, как и должно быть. Этот серый цвет появляется только тогда, когда я устанавливаю градиент.
Эрик Гао
Вы пытались вместо этого установить его на self.detailView.layer.mask? (self.detailView.layer.mask = layer;)
Akaino

Ответы:

185

clearColor имеет канал черного цвета с альфа равным 0, поэтому мне пришлось использовать

[UIColor colorWithWhite:1 alpha:0]

и работает нормально.

Эрик Гао
источник
16
Он заменяет черную тень белой тенью. Все еще непрозрачно
RealNmae
2
Важно - на 2018 год рассмотрите следующий подход: stackoverflow.com/a/25408833/294884
Fattie 06
7
@RealNmae Если вы хотите перейти от одного цвета к другому, используйте UIColor.startColor и UIColor.startColor.withAlphaComponent (0.0) в качестве двух цветов.
Конор
@Conor На самом деле это правильный ответ - спасибо, отлично работает независимо от цвета
SomaMan
60

В Swift это сработало для меня,

UIColor.white.withAlphaComponent(0).cgColor
Мохаммад Заид Патан
источник
3
Не забудьте добавить .cgColor, как показано в ответе !!! Я случайно использовал UIColor.white.withAlphaComponent (0) и час чесал в затылке, гадая, почему он все еще серый.
SnoopyProtocol
21

Стоит отметить, что любой другой цвет будет работать так ... используя комбинацию двух приведенных выше ответов ....

Цель 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
источник
12

Синтаксис Swift 3,

UIColor(white: 1, alpha: 0).cgColor
Стюарт Казаротто
источник
1

Ответы выше, такие как:

UIColor.white.withAlphaComponent(0).cgColor

а также

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

должен работать с точки зрения получения прозрачной части вашего градиента (а не серого, о котором говорит OP). Однако, если вы все еще видите прозрачный белый цвет, хотя должен видеть четкий цвет, убедитесь, что backgroundColorвид, к которому вы применяете градиент, также ясен.

По умолчанию цвет фона этого представления, скорее всего, будет белым (или темным цветом, если устройство находится в темном режиме), поэтому, когда вы применяете градиент, прозрачная его часть будет «заблокирована» самим представлением backgroundColor. Установите его на очистку, и все будет в порядке.

Брайан Сачетта
источник
0

Как и многие, я получил серый цвет, несмотря на то, что использовал чистый белый цвет.

Поэтому я изменил свой подход и выбрал маску, а не градиент. Конечный результат такой же, ну, лучше, так как этот работает во всех ситуациях, а не только если у вас есть подходящий фон.

Я не пробовал использовать этот код с IB, но, надеюсь, он тоже работает. Просто установите, backgroundColorи все готово .

@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
источник
0

Стоит отметить, что для обработки градиентов белого / черного (или действительно любого цвета со светлым / темным оттенком) на основе режима свет / темнота в iOS 13 этот подход также работает с новыми системными цветами:

gradientLayer.colors = [
    UIColor.systemBackground.cgColor,
    UIColor.systemBackground.withAlphaComponent(0).cgColor] 
Джейк
источник