从UICollectionView cellForItemAt indexPath设置CAShapeLayer动画的toValue [英] Setting toValue for CAShapeLayer animation from UICollectionView cellForItemAt indexPath

查看:177
本文介绍了从UICollectionView cellForItemAt indexPath设置CAShapeLayer动画的toValue的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我包括以下部分:
-我的主视图是带有UICollectionView的UIViewController
-UICollectionView的单元格
-UIView的子类,用于使用CABasicAnimation构建CAShapeLayer

I have the following parts: - My main view is a UIViewController with a UICollectionView - The cell for the UICollectionView - A subclass of the UIView to build a CAShapeLayer with an CABasicAnimation

在我的主视图中,我有一个UICollectionView,它渲染一堆带有标签等的单元格。它还显示了一个进度图。

In my main view I have a UICollectionView which renders a bunch of cells with labels etc. It also is showing a progress graph.

在我的子类ProgressCirclePath()中,我正在绘制一个CAShapeLayer,它充当UICollectionView的每个单元格中呈现的进度图。

In my subclass ProgressCirclePath() I am drawing a CAShapeLayer which is acting as the progress graph rendered in each cell of my UICollectionView.

我已经能够将数据传递到每个单元格,例如标签以及CAShapeLayer strokeEnd值。

I have been able to pass data to each cell, e.g. the labels as well as the CAShapeLayer strokeEnd values.

在我尝试将CABasicAnimation添加到路径之前,一切都很好。在这种情况下,我无法将动画的值设置为Value。使用打印控制台进行测试后发现,该值在我的UICollectionView中可用,但在我的子类的动画块中不可用(该值仅返回nil)。我尝试过简单地设置toValue以及在我的ProgressCirlePath中创建变量并从UICollectionView进行设置。两者都不起作用。

Everything is fine until I try to add a CABasicAnimation to my path. In this case I am not able to set the value for the animations toValue. Testing using the print console reveals that the value is available in my UICollectionView but not in the animation block in my subClass (which is where it simply returns nil). I have tried simply setting the toValue as well as creating a variable within my ProgressCirlePath and setting it from the UICollectionView. Neither worked.

我很感谢有关为什么发生这种情况以及如何解决此问题的任何提示。谢谢!!

I'd appreciate any hints on why this is happening and how to solve this. Thanks!!

在我的UICollectionView中:

Within my UICollectionView:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
      let cell = decksCollectionView.dequeueReusableCell(withReuseIdentifier: "DeckCell", for: indexPath) as! DeckCell

  cell.creatorLabel.text = deckCellCreator[indexPath.item]
  cell.titleLabel.text = deckCellTitle[indexPath.item]
  cell.progressLabel.text = "\(deckCellCompletionPercentage[indexPath.item])%"

  cell.progressGraphView.animation.toValue = CGFloat(deckCellCompletionPercentage[indexPath.item])/100

  return cell
}

我的单元格类别中的设置:

The setup within my cell class:

let progressGraphView: ProgressCirclePath = {
    let circlePath = ProgressCirclePath(frame: CGRect(x:0, y:0, width: 86, height: 86))
    circlePath.progressLayer.position = circlePath.center
    circlePath.progressBackgroundLayer.position = circlePath.center
    circlePath.translatesAutoresizingMaskIntoConstraints = false
    return circlePath
}()

这是我的ProgressCirclePath()

And here my ProgressCirclePath()

class ProgressCirclePath: UIView {
let progressLayer = CAShapeLayer()
let progressBackgroundLayer = CAShapeLayer()
let animation = CABasicAnimation(keyPath: "strokeEnd")
//    var percentageValue = CGFloat()


override init(frame: CGRect) {
    super.init(frame: frame)

    layer.addSublayer(progressBackgroundLayer)
    layer.addSublayer(progressLayer)

    let circularPath = UIBezierPath(arcCenter: .zero, radius: 43, startAngle: 0, endAngle: 2*CGFloat.pi, clockwise: true)

    progressBackgroundLayer.path = circularPath.cgPath
    progressBackgroundLayer.lineWidth = 10
    progressBackgroundLayer.strokeStart = 0
    progressBackgroundLayer.strokeEnd = 1
    progressBackgroundLayer.strokeColor = UIColor(red: 221/255.0, green: 240/255.0, blue: 226/255.0, alpha: 1.0).cgColor
    progressBackgroundLayer.fillColor = UIColor.clear.cgColor
    progressBackgroundLayer.transform = CATransform3DMakeRotation(-CGFloat.pi/2, 0, 0, 1)

    progressLayer.path = circularPath.cgPath
    progressLayer.lineWidth = 10
    progressLayer.lineCap = kCALineCapRound
    progressLayer.strokeColor = UIColor(red: 72/255.0, green: 172/255.0, blue: 104/255.0, alpha: 1.0).cgColor
    progressLayer.fillColor = UIColor.clear.cgColor
    progressLayer.transform = CATransform3DMakeRotation(-CGFloat.pi/2, 0, 0, 1)


    animation.duration = 1
    animation.fromValue = 0
    // animation.toValue = percentageValue
    animation.fillMode = kCAFillModeForwards
    animation.isRemovedOnCompletion = false
    progressLayer.add(animation, forKey: "animateGraph")
    print("animation.toValue \(animation.toValue)")
}

required init?(coder aDecoder: NSCoder) {
    fatalError("has not been implemented")
}

}

推荐答案

您要在生命周期的早期处理数据和动画的注入自定义视图。与其在对象的初始值设定项中处理它们,不如将它们移至以后更合适的方法,例如 layoutSubviews

You're handling the injection of data and animation too early in the lifecycle of the custom view. Instead of handling them in the object's initializer, move them to a later and more appropriate method, such as layoutSubviews:

override open func layoutSubviews() {
    super.layoutSubviews()

    // handle post-init stuff here, like animations and passing in data
    // when it doesn't get passed in on init

}

这篇关于从UICollectionView cellForItemAt indexPath设置CAShapeLayer动画的toValue的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆