Skip to main content
Code Review

Return to Answer

edited body
Source Link
Martin R
  • 24.2k
  • 2
  • 37
  • 95

There is one problem with your approach: Additional sublayers are added in draw() and in animateTimerReset() and never removed. That can cause memory problems and slower drawing eventually.

I would suggest to create and add only a single instance of the animation layer, this can for example be done in

override func awakeFromNib() {
 layer.addSublayer(animationLayer)
}

Then animate this single animation layer:

func animateTimer(over duration: TimeInterval) {
 animationLayer.removeAllAnimations()
 let head = CABasicAnimation(keyPath: "strokeEnd")
 head.toValue = 1
 head.duration = duration
 head.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
 head.fillMode = kCAFillModeForwards
 head.isRemovedOnCompletion = false
 animationLayer.add(head, forKey: "strokeEnd")
}
func animateTimerReset() {
 let tail = CABasicAnimation(keyPath: "strokeStart")
 tail.toValue = 1
 tail.duration = 0.1
 tail.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
 tail.fillMode = kCAFillModeForwards
 tail.isRemovedOnCompletion = false
 animationLayer.add(tail, forKey: "strokeStart")
}

Some further remarks: At several places the explicit type annotation can be removed, e.g.

var trackColor: UIColor = UIColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
var trackShade: UIColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.6)
var trackLight: UIColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.3)

is shortedshorter written as

var trackColor = UIColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
var trackShade = UIColor(red: 0, green: 0, blue: 0, alpha: 0.6)
var trackLight = UIColor(red: 1, green: 1, blue: 1, alpha: 0.3)

Also the type"implicit member expressions" can be removedused if itthe type is inferred from the context, e e.g.

layer.strokeEnd = CGFloat.leastNormalMagnitude

becomes

layer.strokeEnd = .leastNormalMagnitude

There is one problem with your approach: Additional sublayers are added in draw() and in animateTimerReset() and never removed. That can cause memory problems and slower drawing eventually.

I would suggest to create and add only a single instance of the animation layer, this can for example be done in

override func awakeFromNib() {
 layer.addSublayer(animationLayer)
}

Then animate this single animation layer:

func animateTimer(over duration: TimeInterval) {
 animationLayer.removeAllAnimations()
 let head = CABasicAnimation(keyPath: "strokeEnd")
 head.toValue = 1
 head.duration = duration
 head.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
 head.fillMode = kCAFillModeForwards
 head.isRemovedOnCompletion = false
 animationLayer.add(head, forKey: "strokeEnd")
}
func animateTimerReset() {
 let tail = CABasicAnimation(keyPath: "strokeStart")
 tail.toValue = 1
 tail.duration = 0.1
 tail.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
 tail.fillMode = kCAFillModeForwards
 tail.isRemovedOnCompletion = false
 animationLayer.add(tail, forKey: "strokeStart")
}

Some further remarks: At several places the explicit type annotation can be removed, e.g.

var trackColor: UIColor = UIColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
var trackShade: UIColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.6)
var trackLight: UIColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.3)

is shorted written as

var trackColor = UIColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
var trackShade = UIColor(red: 0, green: 0, blue: 0, alpha: 0.6)
var trackLight = UIColor(red: 1, green: 1, blue: 1, alpha: 0.3)

Also the type can be removed if it is inferred from the context, e.g.

layer.strokeEnd = CGFloat.leastNormalMagnitude

becomes

layer.strokeEnd = .leastNormalMagnitude

There is one problem with your approach: Additional sublayers are added in draw() and in animateTimerReset() and never removed. That can cause memory problems and slower drawing eventually.

I would suggest to create and add only a single instance of the animation layer, this can for example be done in

override func awakeFromNib() {
 layer.addSublayer(animationLayer)
}

Then animate this single animation layer:

func animateTimer(over duration: TimeInterval) {
 animationLayer.removeAllAnimations()
 let head = CABasicAnimation(keyPath: "strokeEnd")
 head.toValue = 1
 head.duration = duration
 head.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
 head.fillMode = kCAFillModeForwards
 head.isRemovedOnCompletion = false
 animationLayer.add(head, forKey: "strokeEnd")
}
func animateTimerReset() {
 let tail = CABasicAnimation(keyPath: "strokeStart")
 tail.toValue = 1
 tail.duration = 0.1
 tail.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
 tail.fillMode = kCAFillModeForwards
 tail.isRemovedOnCompletion = false
 animationLayer.add(tail, forKey: "strokeStart")
}

Some further remarks: At several places the explicit type annotation can be removed, e.g.

var trackColor: UIColor = UIColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
var trackShade: UIColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.6)
var trackLight: UIColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.3)

is shorter written as

var trackColor = UIColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
var trackShade = UIColor(red: 0, green: 0, blue: 0, alpha: 0.6)
var trackLight = UIColor(red: 1, green: 1, blue: 1, alpha: 0.3)

Also "implicit member expressions" can be used if the type is inferred from the context, e.g.

layer.strokeEnd = CGFloat.leastNormalMagnitude

becomes

layer.strokeEnd = .leastNormalMagnitude
Source Link
Martin R
  • 24.2k
  • 2
  • 37
  • 95

There is one problem with your approach: Additional sublayers are added in draw() and in animateTimerReset() and never removed. That can cause memory problems and slower drawing eventually.

I would suggest to create and add only a single instance of the animation layer, this can for example be done in

override func awakeFromNib() {
 layer.addSublayer(animationLayer)
}

Then animate this single animation layer:

func animateTimer(over duration: TimeInterval) {
 animationLayer.removeAllAnimations()
 let head = CABasicAnimation(keyPath: "strokeEnd")
 head.toValue = 1
 head.duration = duration
 head.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
 head.fillMode = kCAFillModeForwards
 head.isRemovedOnCompletion = false
 animationLayer.add(head, forKey: "strokeEnd")
}
func animateTimerReset() {
 let tail = CABasicAnimation(keyPath: "strokeStart")
 tail.toValue = 1
 tail.duration = 0.1
 tail.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
 tail.fillMode = kCAFillModeForwards
 tail.isRemovedOnCompletion = false
 animationLayer.add(tail, forKey: "strokeStart")
}

Some further remarks: At several places the explicit type annotation can be removed, e.g.

var trackColor: UIColor = UIColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
var trackShade: UIColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.6)
var trackLight: UIColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.3)

is shorted written as

var trackColor = UIColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
var trackShade = UIColor(red: 0, green: 0, blue: 0, alpha: 0.6)
var trackLight = UIColor(red: 1, green: 1, blue: 1, alpha: 0.3)

Also the type can be removed if it is inferred from the context, e.g.

layer.strokeEnd = CGFloat.leastNormalMagnitude

becomes

layer.strokeEnd = .leastNormalMagnitude
default

AltStyle によって変換されたページ (->オリジナル) /