我有两排,每排都有一个状态,状态为(等待,进行中,完成)。此外,每行都有标题,imageView,topLine和bottomLine。
根据行的状态,我需要为行进度设置动画,并使用动画更改imageView中的图像。
到目前为止,我已经使用动画完成了imageView中的图像更改,但这还不是很完美。滚动时显示动画。另外,我尝试使用UIBezierPath进行行进度动画处理,但没有成功。滚动时会波动。 Sample Image
我要实现,线条将用动画绘制,并且图像只有在线条在单元格上设置动画时才会改变。滚动tableView时,它不应波动。
一些代码参考
在cellForRowAtindexPath
let cell = tableview.dequeueReusableCell(withIdentifier: "AnimationTableViewCell") as? AnimationTableViewCell
// code block without animation. Only image animation done but its not perfect
/*switch indexPath.row {
case 0:
let firstIndex = 0
let nextIndex = 1
cell?.animateFrom(first: arrItem[firstIndex], to: arrItem[nextIndex])
case arrItem.count - 1:
let currentIndex = indexPath.row
let prevIndex = currentIndex - 1
cell?.animateFrom(previous: arrItem[prevIndex], to: arrItem[currentIndex])
default:
let currentIndex = indexPath.row
let prevIndex = currentIndex - 1
let nextIndex = currentIndex + 1
cell?.animate(previous: arrItem[prevIndex], current: arrItem[currentIndex], next: arrItem[nextIndex])
}
cell?.changeImageWithAnimation(arrItem[indexPath.row].state, row: indexPath.row)*/
// code block with improper animation
if (cell?.shapeLayer == nil) {
cell?.doAnimation(state: arrItem[indexPath.row].state, row: indexPath.row, isFirstTime: firstTime)
}
cell?.lblTitle.text = arrItem[indexPath.row].title
cell?.clipsToBounds = true
cell?.selectionStyle = .none
return cell!
在AnimationTableViewCell中
func doAnimation(state: ProgressType, row: Int = 0, isFirstTime: Bool) {
NSLog("\(row)")
guard isFirstTime else {
return
}
// DispatchQueue.main.asyncAfter(deadline: <#T##DispatchTime#>, execute: <#T##() -> Void#>)
DispatchQueue.main.asyncAfter(deadline: (DispatchTime.now() + .seconds(row))) {
self.shapeLayer?.removeFromSuperlayer()
// create whatever path you want
let path = UIBezierPath()
path.move(to: CGPoint(x: self.lblTopLine.frame.origin.x, y: 0))
path.addLine(to: CGPoint(x: self.lblTopLine.frame.origin.x, y: 74))
path.addLine(to: CGPoint(x: self.lblTopLine.frame.origin.x, y: 148))
// create shape layer for that path
let shapeLayer = CAShapeLayer()
shapeLayer.fillColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0).cgColor
shapeLayer.strokeColor = state.color().cgColor
// shapeLayer.strokeColor = #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1).cgColor
shapeLayer.lineWidth = 4
shapeLayer.path = path.cgPath
// animate it
self.layer.addSublayer(shapeLayer)
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = 0
animation.duration = 1
shapeLayer.add(animation, forKey: "MyAnimation")
// save shape layer
self.shapeLayer = shapeLayer
DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
// self.lblTopLine.backgroundColor = state.color()
// self.lblBottomLine.backgroundColor = state.color()
// self.shapeLayer?.removeFromSuperlayer()
})
self.imgView.image = UIImage(named: "initial")
self.imgView.backgroundColor = UIColor.clear
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(250), execute: {
UIView.animate(withDuration: 0.5, animations: {
self.imgView.backgroundColor = UIColor.red
})
UIView.transition(with: self.imgView, duration: 0.5, options: UIView.AnimationOptions.transitionCrossDissolve, animations: {
self.imgView.image = UIImage(named: "tick")
}, completion: nil)
})
}
}
您可以从here下载示例项目。