Не удается анимировать свойство местоположений для CAGradientLayer при изменении количества местоположений - PullRequest
0 голосов
/ 14 октября 2018

Я создал UICollectionView, где верх и низ вида имеют градиент.При прокрутке до нижней части экрана градиент исчезает.Я хочу оживить это изменение.

В моем UICollectionView классе:

func setupTopAndBottomGradientMask() {
    let coverView = GradientView(frame: self.bounds)
    guard let coverLayer = coverView.layer as? CAGradientLayer else {
        return
    }
    coverLayer.colors = [UIColor.clear.cgColor, 
    UIColor.black.cgColor, UIColor.black.cgColor, UIColor.clear.cgColor]
    coverLayer.locations = [0.0, 0.07, 0.93, 1.0]
    self.mask = coverView
}

func setupTopGradientMask() {
    let coverView = GradientView(frame: self.bounds)
    guard let coverLayer = coverView.layer as? CAGradientLayer else {
        return
    }
    coverLayer.colors = [UIColor.clear.cgColor, UIColor.black.cgColor]
    coverLayer.locations = [0.0, 0.07]
    self.mask = coverView
}

В scrollViewDidScroll в моем UIViewController Я добавил код для анимации перехода из состояния setupTopAndBottomGradientMask() в состояние setupTopGradientMask():

    let colorsAnimation = CABasicAnimation(keyPath: "colors")
    colorsAnimation.fromValue = [UIColor.clear.cgColor, UIColor.black.cgColor, 
    UIColor.black.cgColor, UIColor.clear.cgColor]
    colorsAnimation.toValue = [UIColor.clear.cgColor, UIColor.black.cgColor]

    let locationsAnimation = CABasicAnimation(keyPath: "locations")
    locationsAnimation.fromValue = [0.0, 0.07, 0.93, 1.0]
    locationsAnimation.toValue = [0.0, 0.07]

    let removeBottomGradientAnimationGroup = CAAnimationGroup()
    removeBottomGradientAnimationGroup.animations = [colorsAnimation, 
    locationsAnimation]
    removeBottomGradientAnimationGroup.duration = 2
    removeBottomGradientAnimationGroup.timingFunction = 
    CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)

    let existingMaskLayer =  mainCollectionView.mask?.layer as? CAGradientLayer
    existingMaskLayer?.colors = [UIColor.clear.cgColor, UIColor.black.cgColor]
    existingMaskLayer?.locations = [0.0, 0.07]
    mainCollectionView.mask?.layer.add(removeBottomGradientAnimationGroup, forKey: "removeBottomGradientAnimationGroup")

Этот код создает правильный конечный интерфейс, но не анимирует. Это скринкаст пользовательского интерфейса, в котором градиент изменяется, но не анимируется

Я подтвердил, что если массив местоположений имеет одинаковый размер для locationsAnimation.fromValue и locationsAnimation.toValue, то он анимирует.

Мой вопрос: Как я могу добиться нужной анимации, если учесть, что CABasicAnimation не поддерживает анимацию между CAGradientLayers с разным количеством местоположений?

1 Ответ

0 голосов
/ 14 октября 2018

Меня не удивляет, что это происходит.Есть похожая проблема с анимацией пути в CAShapeLayer.В этом случае количество и тип контрольных точек на пути должны быть одинаковыми в начале и в конце, или результаты анимации не определены.

Вам необходимо найти эквивалентную анимацию, которая по-прежнему имеет 4 цвета вмассив.

Вы анимируете от [clear, black, black, clear] до [clear, black] и от местоположений [0.0, 0.07, 0.93, 1.0] до [0.0, 0.07].

Почему бы не анимировать от [clear, black, black, clear] до [clear, black, black, black] с одинаковыми начальными и конечными местоположениями.Это должно дать тот же эффект.

...