ios - 当位置数发生变化时,无法为 CAGradientLayer 的位置属性设置动画

标签 ios swift core-animation

我创建了一个 UICollectionView,其中 View 的顶部和底部具有渐变。当您滚动到 View 底部时,渐变消失。我想为这种变化制作动画。

在我的 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
}

在我的 UIViewControllerscrollViewDidScroll 中,我添加了代码以动画化从 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")

这段代码创建了正确的最终用户界面,但它没有动画。 This is a screencast of UI where the gradient changes but does not animate

我确认如果 locationsAnimation.fromValuelocationsAnimation.toValue 的位置数组大小相同,那么它会生成动画。

我的问题:如果 CABasicAnimation 不支持在具有不同数量位置的 CAGradientLayers 之间设置动画,我该如何实现我想要的动画?

最佳答案

发生这种情况我并不感到惊讶。在 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] 制作动画。这应该会产生相同的效果。

关于ios - 当位置数发生变化时,无法为 CAGradientLayer 的位置属性设置动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52798871/

相关文章:

ios - 使用带有完成处理程序的循环在多个节点上使用单个 SKAction 动画

ios - 具有多个原型(prototype)单元格的 Collection View 以及在 MVVM 下处理它们的通用方法

iphone - 运动的核心动画公式

objective-c - 如何将包含核心动画层的 View 渲染到位图?

ios - 使用 SQLITE 的 Swift 应用程序在更新数据库后崩溃。 SQLITE 文件未复制到文件/包

ios - 2 使用 UIPageViewController 的页面 View

ios - AFNetworking 中 "setImageWithURLRequest: placeholderImage: success:"的 Alamofire 方式

ios - 什么类型的 HealthKit 单元用于 VO2 Max 测量? - swift 4

ios - Apple Geofencing 失败当位置服务设置 "only while using the app"

objective-c - 使按钮能够被拖放