动画视图的子视图不适用于 CAGradientLayer [关闭]

Posted

技术标签:

【中文标题】动画视图的子视图不适用于 CAGradientLayer [关闭]【英文标题】:Animate view's subViews is not working with CAGradientLayer [closed] 【发布时间】:2017-01-22 18:13:14 【问题描述】:

我想在我的应用程序中使用 CAGradientLayer。我在 viewController 的视图子层的索引 0 处插入了一个 CAGradientLayer:

class ViewController: UIViewController 
var label: UILabel!

override func viewDidLoad() 
    let width = view.frame.size.width
    let height = view.frame.size.height
    super.viewDidLoad()
    label = UILabel(frame: CGRect(x: 30, y: 80, width: width/4, height: height/20))
    label.backgroundColor = UIColor.yellow
    label.textColor = UIColor.white
    label.text = "label"
    label.alpha = 0
    view.addSubview(label)
    let hideButton = UIButton.init(type: .system)
    hideButton.frame = CGRect(x: width/2 - 15, y: label.frame.origin.y + 50, width: width/4, height: 30)
    hideButton.setTitle("Hide", for: .normal)
    hideButton.backgroundColor = UIColor.red
    hideButton.addTarget(self, action: #selector(ViewController.fadeOutLabel), for: .touchUpInside)
    view.addSubview(hideButton)

    let gradientButton = UIButton.init(type: .system)
    gradientButton.frame = CGRect(x: width/2 - 15, y: hideButton.frame.origin.y + 50, width: width/4, height: 30)
    gradientButton.setTitle("add gradient", for: .normal)
    gradientButton.backgroundColor = UIColor.red
    gradientButton.addTarget(self, action: #selector(ViewController.updateSubviews), for: .touchUpInside)
    view.addSubview(gradientButton)



func updateSubviews() 
    UIView.animate(withDuration: 0.3, animations: 
        self.label.alpha = 1
        let gradientSublayer = self.makeGradientLayer()
        self.view.layer.insertSublayer(gradientSublayer, at: 0)
        , completion: nil)


func makeGradientLayer() -> CAGradientLayer
    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = UIScreen.main.bounds
    let primaryColor = UIColor.yellow
    let secondaryColor = UIColor.green
    gradientLayer.colors = [primaryColor.cgColor, secondaryColor.cgColor]
    return gradientLayer


func fadeOutLabel()
    print("touch received")
    UIView.animate(withDuration: 0.3, animations:  
        self.label.alpha = 0
        )  (finished) in
            print("animation finished")
    

但是,我在屏幕上有其他 UI 元素,它们是可见的,但是当我尝试添加一些动画(点击按钮或更改其文本时为标签的 alpha 设置动画)时,它不起作用。按钮的选择器触发,然后动画块执行......但没有任何反应。我尝试了最明显的解决方案——创建一个单独的视图并将其添加为子视图,但结果不会改变。控制器上的所有子视图都被添加到 viewDidLoad 中的主视图中。也许我错过了关于 CALayers 的一些东西?

【问题讨论】:

我没有看到任何“动画块”。你在说什么? @matt 我说的是 UIView.animate(withDuration: , animations: Void#>) 这只是在另一个放在代码中。它在点击时触发,但子视图没有任何反应。例如,我在动画块中将 label.alpha 设置为 0,并且正在执行该行。但是标签并没有真正发生任何变化,它仍然可见! 但是您需要在question中显示实际代码。我需要能够重现问题以帮助解决它。所以请展示更多你的代码。 @matt 我已经制作了一个示例应用程序并在问题中添加了一些代码,但它工作正常,因此我无法重现错误。 太棒了!做得非常好。这是我最喜欢的调试技术之一。所以现在你知道这应该有效。使用它与您的实际应用程序之间的差异来找出导致问题的原因。我敢打赌,事实证明这完全不相关,您甚至没有在问题中告诉我们。 — 通过将您的应用程序置于版本控制之下,您可以愉快地开始从中删除内容,直到您不小心删除了问题的原因。另一个很棒的技术。 【参考方案1】:

在我的原始代码中,我在 viewWillLayoutSubviews() 中添加了标签和其他子视图。我将所有内容移至 viewDidLoad() 并且动画开始工作。不幸的是,我无法在示例项目中重现它。仍然不确定我是不是错了。

【讨论】:

以上是关于动画视图的子视图不适用于 CAGradientLayer [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

单击手势不适用于以编程方式添加的子视图

停止动画不适用于图像视图

UIScrollView 作为 UIView 的子视图不适用于自动布局

动画不适用于 SwiftUI 视图状态更改

使用NSView.layoutSubtreeIfNeeded()动画自动布局约束不适用于macOS High Sierra

UIScrollView 不适用于 EXC_BAD_ACCESS